source('../env.R')
Using GitHub PAT from the git credential store.
Skipping install of 'clootl' from a github remote, the SHA1 (2ed1650b) has not changed since last install.
  Use `force = TRUE` to force installation
community_data = read_csv(filename(COMMUNITY_OUTPUT_DIR, 'community_assembly_metrics_using_relative_abundance.csv'))
Rows: 308 Columns: 10── Column specification ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
dbl (10): mntd_standard, mntd_actual, mass_fdiv_standard, mass_fdiv_actual, beak_width_fdiv_standard, beak_width_fdiv_actual, hwi_fdiv_...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(community_data)
colnames(community_data)
 [1] "mntd_standard"            "mntd_actual"              "mass_fdiv_standard"       "mass_fdiv_actual"         "beak_width_fdiv_standard"
 [6] "beak_width_fdiv_actual"   "hwi_fdiv_standard"        "hwi_fdiv_actual"          "city_id"                  "urban_pool_size"         
min(community_data$mntd_standard)
[1] -2.33692
max(community_data$mntd_standard)
[1] 2.328448
min(community_data$beak_width_fdiv_standard)
[1] -2.685152
max(community_data$beak_width_fdiv_standard)
[1] 1.931681
min(community_data$hwi_fdiv_standard)
[1] -2.200336
max(community_data$hwi_fdiv_standard)
[1] 2.333383
min(community_data$mass_fdiv_standard)
[1] -2.377212
max(community_data$mass_fdiv_standard)
[1] 2.1073

Join on realms

city_to_realm = read_csv(filename(CITY_DATA_OUTPUT_DIR, 'realms.csv'))
Rows: 337 Columns: 2── Column specification ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (1): core_realm
dbl (1): city_id
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
community_data_with_realm = left_join(community_data, city_to_realm)
Joining with `by = join_by(city_id)`

Cities as points

city_points = st_centroid(read_sf(filename(CITY_DATA_OUTPUT_DIR, 'city_selection.shp'))) %>% left_join(community_data_with_realm)
Warning: st_centroid assumes attributes are constant over geometriesWarning: st_centroid does not give correct centroids for longitude/latitude dataJoining with `by = join_by(city_id)`
city_points_coords = st_coordinates(city_points)
city_points$latitude = city_points_coords[,1]
city_points$longitude = city_points_coords[,2]
world_map = read_country_boundaries()

Load community data, and create long format version

communities = read_csv(filename(COMMUNITY_OUTPUT_DIR, 'communities_for_analysis.csv'))
Rows: 2428 Columns: 7── Column specification ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (5): city_name, ebird_species_name, seasonal, presence, origin
dbl (2): city_id, relative_abundance_proxy
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
communities
community_summary = communities %>% group_by(city_id) %>% summarise(regional_pool_size = n(), urban_pool_size = sum(relative_abundance_proxy > 0))
community_summary

Load trait data

traits = read_csv(filename(TAXONOMY_OUTPUT_DIR, 'traits_ebird.csv'))
Rows: 332 Columns: 10── Column specification ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (5): ebird_species_name, habitat, trophic_level, trophic_niche, primary_lifestyle
dbl (5): beak_width, hwi, mass, habitat_density, migration
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(traits)

Load realm geo

resolve = read_resolve()
head(resolve)
Simple feature collection with 6 features and 15 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: -162.1547 ymin: -69.55876 xmax: 158.6167 ymax: 61.53428
Geodetic CRS:  WGS 84

Summary metrics by Realm

test_required_values = function(name, df) {
  cat(paste(
    test_value_wilcox(paste(name, 'MNTD'), df$mntd_standard),
    test_value_wilcox(paste(name, 'Beak Gape FDiv'), df$beak_width_fdiv_standard),
    test_value_wilcox(paste(name, 'HWI FDiv'), df$hwi_fdiv_standard),
    test_value_wilcox(paste(name, 'Mass FDiv'), df$mass_fdiv_standard),
    paste('N', nrow(df)),
    sep = "\n"))
}
test_required_values('Global', community_data_with_realm)
Global MNTD median -0.36 ***
Global Beak Gape FDiv median 0.02 
Global HWI FDiv median 0.39 **
Global Mass FDiv median 0.29 ***
N 308
unique(community_data_with_realm$core_realm)
[1] "Nearctic"    "Neotropic"   "Palearctic"  "Afrotropic"  "Indomalayan" "Australasia"
test_required_values('Nearctic', community_data_with_realm[community_data_with_realm$core_realm == 'Nearctic',])
Nearctic MNTD median 0.67 *
Nearctic Beak Gape FDiv median 0.29 
Nearctic HWI FDiv median -0.8 ***
Nearctic Mass FDiv median -0.26 
N 46
test_required_values('Neotropic', community_data_with_realm[community_data_with_realm$core_realm == 'Neotropic',])
Neotropic MNTD median 0.03 
Neotropic Beak Gape FDiv median -0.44 ***
Neotropic HWI FDiv median -0.31 
Neotropic Mass FDiv median 0.33 *
N 64
test_required_values('Palearctic', community_data_with_realm[community_data_with_realm$core_realm == 'Palearctic',])
Palearctic MNTD median 0.13 
Palearctic Beak Gape FDiv median 1.25 ***
Palearctic HWI FDiv median -0.39 
Palearctic Mass FDiv median 0.01 
N 72
test_required_values('Afrotropic', community_data_with_realm[community_data_with_realm$core_realm == 'Afrotropic',])
Afrotropic MNTD median -1.28 *
Afrotropic Beak Gape FDiv median -0.56 
Afrotropic HWI FDiv median 0.15 
Afrotropic Mass FDiv median -0.95 
N 9
test_required_values('Indomalayan', community_data_with_realm[community_data_with_realm$core_realm == 'Indomalayan',])
Indomalayan MNTD median -0.64 ***
Indomalayan Beak Gape FDiv median -0.68 ***
Indomalayan HWI FDiv median 1.11 ***
Indomalayan Mass FDiv median 0.83 ***
N 111
test_required_values('Australasia', community_data_with_realm[community_data_with_realm$core_realm == 'Australasia',])
Australasia MNTD median -1.39 
Australasia Beak Gape FDiv median -0.75 
Australasia HWI FDiv median 0.77 
Australasia Mass FDiv median -0.96 
N 6

What families exist in which realms?

communities %>% 
  left_join(city_to_realm) %>% 
  mutate(family = gsub( "_.*$", "", ebird_species_name)) %>%
  dplyr::select(family, core_realm) %>%
  distinct() %>%
  arrange(core_realm)
Joining with `by = join_by(city_id)`

Summary metrics by introduced species

communities = read_csv(filename(COMMUNITY_OUTPUT_DIR, 'communities_for_analysis.csv'))
Rows: 2428 Columns: 7── Column specification ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (5): city_name, ebird_species_name, seasonal, presence, origin
dbl (2): city_id, relative_abundance_proxy
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
city_introduced_species = communities %>% group_by(city_id) %>% summarise(number_of_species = n()) %>% left_join(
  communities %>% group_by(city_id) %>% filter(origin == 'Introduced') %>% summarise(number_of_introduced_species = n())
) %>% replace_na(list(number_of_introduced_species = 0))
Joining with `by = join_by(city_id)`
community_data_with_introductions = left_join(community_data, city_introduced_species)
Joining with `by = join_by(city_id)`
community_data_with_introductions$has_introduced_species = community_data_with_introductions$number_of_introduced_species > 0
community_data_with_introductions
community_data_with_introductions[,c('mntd_standard', 'has_introduced_species')]
community_data_with_introductions %>% group_by(has_introduced_species) %>% summarise(
  total_cities = n(), 
  
  mean_mntd_std = mean(mntd_standard, na.rm = T),
  median_mntd_std = median(mntd_standard, na.rm = T),
  sd_mntd_std = sd(mntd_standard, na.rm = T),
  
  mean_mass_fdiv_std = mean(mass_fdiv_standard, na.rm = T),
  median_mass_fdiv_std = median(mass_fdiv_standard, na.rm = T),
  sd_mass_fdiv_std = sd(mass_fdiv_standard, na.rm = T),
  
  mean_gape_width_fdiv_std = mean(beak_width_fdiv_standard, na.rm = T),
  median_gape_width_fdiv_std = median(beak_width_fdiv_standard, na.rm = T),
  sd_gape_width_fdiv_std = sd(beak_width_fdiv_standard, na.rm = T),
  
  mean_handwing_index_fdiv_std = mean(hwi_fdiv_standard, na.rm = T),
  median_handwing_index_fdiv_std = median(hwi_fdiv_standard, na.rm = T),
  sd_handwing_index_fdiv_std = sd(hwi_fdiv_standard, na.rm = T)
)

MNTD

ggplot(community_data_with_introductions, aes(x = has_introduced_species, y = mntd_standard)) + geom_boxplot()

wilcox.test(mntd_standard ~ has_introduced_species, community_data_with_introductions, na.action = 'na.omit')

    Wilcoxon rank sum test with continuity correction

data:  mntd_standard by has_introduced_species
W = 7925, p-value = 0.00001285
alternative hypothesis: true location shift is not equal to 0

There is a significant difference between the response of cities with introduced species (0.53±0.27) and those without (0.47±0.19) (p-value = 0.02).

Mass FDiv

ggplot(community_data_with_introductions, aes(x = has_introduced_species, y = mass_fdiv_standard)) + geom_boxplot()

wilcox.test(mass_fdiv_standard ~ has_introduced_species, community_data_with_introductions, na.action = 'na.omit')

    Wilcoxon rank sum test with continuity correction

data:  mass_fdiv_standard by has_introduced_species
W = 15028, p-value = 0.0000006706
alternative hypothesis: true location shift is not equal to 0

There is a significant difference between the response of cities with introduced species (0.57±0.27) and those without (0.73±0.24) (p < 0.0001)

Beak Gape FDiv

ggplot(community_data_with_introductions, aes(x = has_introduced_species, y = beak_width_fdiv_standard)) + geom_boxplot()

wilcox.test(beak_width_fdiv_standard ~ has_introduced_species, community_data_with_introductions, na.action = 'na.omit')

    Wilcoxon rank sum test with continuity correction

data:  beak_width_fdiv_standard by has_introduced_species
W = 8662, p-value = 0.0006884
alternative hypothesis: true location shift is not equal to 0

There is NOT a significant difference between the response of cities with introduced species (0.61±0.30) and those without (0.56±0.27)

HWI FDiv

ggplot(community_data_with_introductions, aes(x = has_introduced_species, y = hwi_fdiv_standard)) + geom_boxplot()

wilcox.test(hwi_fdiv_standard ~ has_introduced_species, community_data_with_introductions, na.action = 'na.omit')

    Wilcoxon rank sum test with continuity correction

data:  hwi_fdiv_standard by has_introduced_species
W = 17606, p-value < 0.00000000000000022
alternative hypothesis: true location shift is not equal to 0

There is a significant difference between the response of cities with introduced species (0.49±0.30) and those without (0.79±0.21) (p < 0.0001)

Examine individual metrics

Analysis data frame

geography = read_csv(filename(CITY_DATA_OUTPUT_DIR, 'geography.csv'))
Rows: 342 Columns: 26── Column specification ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
dbl (26): city_id, city_avg_ndvi, city_avg_elevation, city_avg_temp, city_avg_min_monthly_temp, city_avg_max_monthly_temp, city_avg_mon...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
names(geography)
 [1] "city_id"                       "city_avg_ndvi"                 "city_avg_elevation"            "city_avg_temp"                
 [5] "city_avg_min_monthly_temp"     "city_avg_max_monthly_temp"     "city_avg_monthly_temp"         "city_avg_rainfall"            
 [9] "city_avg_max_monthly_rainfall" "city_avg_min_monthly_rainfall" "city_avg_soil_moisture"        "city_max_elev"                
[13] "city_min_elev"                 "city_elev_range"               "region_20km_avg_ndvi"          "region_20km_avg_elevation"    
[17] "region_20km_avg_soil_moisture" "region_20km_max_elev"          "region_20km_min_elev"          "region_20km_elev_range"       
[21] "region_50km_avg_ndvi"          "region_50km_avg_elevation"     "region_50km_avg_soil_moisture" "region_50km_max_elev"         
[25] "region_50km_min_elev"          "region_50km_elev_range"       
analysis_data = community_data_with_realm[,c('city_id', 'mntd_standard', 'mass_fdiv_standard', 'beak_width_fdiv_standard', 'hwi_fdiv_standard', 'core_realm')] %>% 
  left_join(city_points[,c('city_id', 'latitude', 'longitude')]) %>%
  left_join(community_data_with_introductions[,c('city_id', 'has_introduced_species')]) %>%
  left_join(geography)
Joining with `by = join_by(city_id)`Joining with `by = join_by(city_id)`Joining with `by = join_by(city_id)`
analysis_data$abs_latitude = abs(analysis_data$latitude)
analysis_data$core_realm = factor(analysis_data$core_realm, levels = c('Palearctic', 'Nearctic', 'Neotropic', 'Afrotropic', 'Indomalayan', 'Australasia', 'Oceania'))
analysis_data$has_introduced_species = factor(analysis_data$has_introduced_species, level = c('TRUE', 'FALSE'), labels = c('Introduced species', 'No introduced species'))
model_data = function(df, dependant_var) {
  df[,c(dependant_var, 'core_realm', 'abs_latitude', 'longitude', 'has_introduced_species', 'city_avg_ndvi', 'city_avg_elevation', 'city_avg_temp', 'city_avg_min_monthly_temp', 'city_avg_max_monthly_temp', 'city_avg_monthly_temp', 'city_avg_rainfall', 'city_avg_max_monthly_rainfall', 'city_avg_min_monthly_rainfall', 'city_avg_soil_moisture', 'city_max_elev', 'city_min_elev', 'city_elev_range', 'region_20km_avg_ndvi', 'region_20km_avg_elevation', 'region_20km_avg_soil_moisture', 'region_20km_max_elev', 'region_20km_min_elev', 'region_20km_elev_range', 'region_50km_avg_ndvi', 'region_50km_avg_elevation', 'region_50km_avg_soil_moisture', 'region_50km_max_elev', 'region_50km_min_elev', 'region_50km_elev_range')]
}
model_data(analysis_data, 'mntd_standard')
names(analysis_data)
 [1] "city_id"                       "mntd_standard"                 "mass_fdiv_standard"            "beak_width_fdiv_standard"     
 [5] "hwi_fdiv_standard"             "core_realm"                    "latitude"                      "longitude"                    
 [9] "geometry"                      "has_introduced_species"        "city_avg_ndvi"                 "city_avg_elevation"           
[13] "city_avg_temp"                 "city_avg_min_monthly_temp"     "city_avg_max_monthly_temp"     "city_avg_monthly_temp"        
[17] "city_avg_rainfall"             "city_avg_max_monthly_rainfall" "city_avg_min_monthly_rainfall" "city_avg_soil_moisture"       
[21] "city_max_elev"                 "city_min_elev"                 "city_elev_range"               "region_20km_avg_ndvi"         
[25] "region_20km_avg_elevation"     "region_20km_avg_soil_moisture" "region_20km_max_elev"          "region_20km_min_elev"         
[29] "region_20km_elev_range"        "region_50km_avg_ndvi"          "region_50km_avg_elevation"     "region_50km_avg_soil_moisture"
[33] "region_50km_max_elev"          "region_50km_min_elev"          "region_50km_elev_range"        "abs_latitude"                 
all_explanatories = c(
    'abs_latitude', 'latitude', 'longitude', 
    'has_introduced_species',
    'city_avg_ndvi', 'city_avg_elevation', 'city_avg_temp', 'city_avg_min_monthly_temp', 'city_avg_max_monthly_temp', 
    'city_avg_monthly_temp', 'city_avg_rainfall', 'city_avg_max_monthly_rainfall', 'city_avg_min_monthly_rainfall', 
    'city_avg_soil_moisture', 'city_max_elev', 'city_min_elev', 'city_elev_range',
    'region_20km_avg_ndvi', 'region_20km_avg_elevation', 'region_20km_avg_soil_moisture', 'region_20km_max_elev', 
    'region_20km_min_elev', 'region_20km_elev_range',
    'region_50km_avg_ndvi', 'region_50km_avg_elevation', 'region_50km_avg_soil_moisture', 'region_50km_max_elev', 
    'region_50km_min_elev', 'region_50km_elev_range',
    'core_realmAfrotropic', 'core_realmAustralasia', 'core_realmIndomalayan', 'core_realmNearctic', 'core_realmNeotropic', 'core_realmPalearctic')

type_labels = function(p) {
  explanatory_levels = all_explanatories[all_explanatories %in% p$explanatory]
  p$explanatory <- factor(p$explanatory, levels = explanatory_levels)
  
  p$type <- 'Realm'
  p$type[p$explanatory %in% c('city_avg_ndvi', 'city_avg_elevation', 'city_avg_temp', 'city_avg_min_monthly_temp', 'city_avg_max_monthly_temp', 
    'city_avg_monthly_temp', 'city_avg_rainfall', 'city_avg_max_monthly_rainfall', 'city_avg_min_monthly_rainfall', 
    'city_avg_soil_moisture', 'city_max_elev', 'city_min_elev', 'city_elev_range')] <- 'City geography'
  p$type[p$explanatory %in% c('region_50km_avg_ndvi', 'region_50km_avg_elevation', 'region_50km_avg_soil_moisture', 'region_50km_max_elev', 
    'region_50km_min_elev', 'region_50km_elev_range')] <- 'Regional (50km) geography'
   p$type[p$explanatory %in% c('region_20km_avg_ndvi', 'region_20km_avg_elevation', 'region_20km_avg_soil_moisture', 'region_20km_max_elev', 
    'region_20km_min_elev', 'region_20km_elev_range')] <- 'Regional (20km) geography'
  p$type[p$explanatory %in% c('abs_latitude', 'longitude')] <- 'Spatial'
  p
}
explanatory_labels = c(
  'has_introduced_species'='Has introduced species', 
  'city_avg_ndvi'='Average NDVI', 
  'city_avg_elevation'='Average elevation', 
  'city_avg_temp'='Average temperature', 
  'city_avg_min_monthly_temp'='Average minimum monthly temperature', 
  'city_avg_max_monthly_temp'='Average maximum monthly temperature', 
  'city_avg_monthly_temp'='Average monthly temperature', 
  'city_avg_rainfall'='Average rainfall', 
  'city_avg_max_monthly_rainfall'='Average maximum monthly rainfall', 
  'city_avg_min_monthly_rainfall'='Average minimum monthly rainfall', 
  'city_avg_soil_moisture'='Average soil moisture', 
  'city_max_elev'='Maximum elevation', 
  'city_min_elev'='Minimum elevation', 
  'city_elev_range'='Elevation range', 
  'region_20km_avg_ndvi'='Average NDVI', 
  'region_20km_avg_elevation'='Average elevation', 
  'region_20km_avg_soil_moisture'='Average soil moisture', 
  'region_20km_max_elev'='Maximum elevation', 
  'region_20km_min_elev'='Minimum elevation',
  'region_20km_elev_range'='Elevation range',
  'region_50km_avg_ndvi'='Average NDVI',
  'region_50km_avg_elevation'='Average elevation',
  'region_50km_avg_soil_moisture'='Average soil moisture', 
  'region_50km_max_elev'='Maximum elevation',
  'region_50km_min_elev'='Minimum elevation', 
  'region_50km_elev_range'='Elevation range',
  'abs_latitude' = 'Absolute latitude',
  'latitude' = 'Latitude',
  'longitude' = 'Longitude',
  'core_realmAfrotropic' = 'Afrotropical', 
  'core_realmAustralasia' = 'Austaliasian', 
  'core_realmIndomalayan' = 'Indomalayan', 
  'core_realmNearctic' = 'Nearctic', 
  'core_realmNeotropic' = 'Neotropical',
  'core_realmPalearctic' = 'Palearctic',
  'core_realmOceania' = 'Oceanical')

Helper plot functions

geom_map = function(map_sf, title) {
  norm_mntd_analysis_geo = ggplot() + 
    geom_sf(data = world_map, aes(geometry = geometry)) +
    map_sf +
    standardised_colours_scale +
    labs(colour = 'Standardised\nResponse') +
    theme_bw() +
    theme(legend.position="bottom")
}

Helper Dredge functions

# Taken from MuMIN package
# https://rdrr.io/cran/MuMIn/src/R/averaging.R
# https://rdrr.io/cran/MuMIn/src/R/model.avg.R

.coefarr.avg <-
  function(cfarr, weight, revised.var, full, alpha) {   
    weight <- weight / sum(weight)
    nCoef <- dim(cfarr)[3L]
    if(full) {
      nas <- is.na(cfarr[, 1L, ]) & is.na(cfarr[, 2L, ])
      cfarr[, 1L, ][nas] <- cfarr[, 2L, ][nas] <- 0
      #cfarr[, 1L:2L, ][is.na(cfarr[, 1L:2L, ])] <- 0
      if(!all(is.na(cfarr[, 3L, ])))
        cfarr[ ,3L, ][is.na(cfarr[ , 3L, ])] <- Inf
    }
    
    avgcoef <- array(dim = c(nCoef, 5L),
                     dimnames = list(dimnames(cfarr)[[3L]], c("Estimate",
                                                              "Std. Error", "Adjusted SE", "Lower CI", "Upper CI")))
    for(i in seq_len(nCoef))
      avgcoef[i, ] <- par.avg(cfarr[, 1L, i], cfarr[, 2L, i], weight,
                              df = cfarr[, 3L, i], alpha = alpha, revised.var = revised.var)
    
    avgcoef[is.nan(avgcoef)] <- NA
    return(avgcoef)
  }

.makecoefmat <- function(cf) {
  no.ase <- all(is.na(cf[, 3L]))
  z <- abs(cf[, 1L] / cf[, if(no.ase) 2L else 3L])
  pval <- 2 * pnorm(z, lower.tail = FALSE)
  cbind(cf[, if(no.ase) 1L:2L else 1L:3L, drop = FALSE],
        `z value` = z, `Pr(>|z|)` = zapsmall(pval))
}

# Generate model selections using lmer, dredge, and model.avg
# `forumla` : a two-sided linear formula object describing both the fixed-effects and random-effects part of the model
# `data` : the data frame containing the variables from the formula
# `aic_delta` : the AIC delta to use for selecting models in model average
model_average <- function(formula, data, aic_delta = 20) {
  model <- lm(
    formula,
    data=data
  )
  dredge_result <- dredge(model)
  summary(model.avg(dredge_result, subset = delta < aic_delta))
}

# Create a summary data frame containing the selected variables from a model
# `model_sum` : The model summary output from `model_average`
model_summary <- function(model_sum) {
  .column_name <- function(postfix) {
    postfix
  }
  
  # just return the estimate and p value
  weight <- model_sum$msTable[, 5L]
  
  coefmat.full <- as.data.frame(.makecoefmat(.coefarr.avg(model_sum$coefArray, weight,
                                                          attr(model_sum, "revised.var"), TRUE, 0.05)))
  
  coefmat.subset <-
    as.data.frame(.makecoefmat(.coefarr.avg(model_sum$coefArray, weight,
                                            attr(model_sum, "revised.var"), FALSE, 0.05)))
  
  
  coefmat.subset <- coefmat.subset[-c(1), c(1, 2, 5)]
  names(coefmat.subset) <- c(.column_name("estimate"), .column_name("error"), .column_name("p"))
  coefmat.subset <- tibble::rownames_to_column(coefmat.subset, "explanatory")
  coefmat.subset$model = 'subset'
  
  coefmat.full <- coefmat.full[-c(1), c(1, 2, 5)]
  names(coefmat.full) <- c(.column_name("estimate"), .column_name("error"), .column_name("p"))
  coefmat.full <- tibble::rownames_to_column(coefmat.full, "explanatory")
  coefmat.full$model = 'full'
  
  rbind(coefmat.full, coefmat.subset)
}
formula_from_vsurp = function(predictors, dependent, vsurp_result) {
  as.formula(paste(dependent, paste(names(predictors[,vsurp_result$varselect.interp]), collapse="+"), sep = "~"))
}
plot_vsurp_result = function(result_table) {
  p = result_table[result_table$model == 'full',]
  p = type_labels(p)

  ggplot(p, aes(y=explanatory, x=estimate, colour = type)) + 
    geom_line() +
    geom_point()+
    geom_errorbar(aes(xmin=estimate-error, xmax=estimate+error), width=.2,
                   position=position_dodge(0.05)) +
    scale_y_discrete(
      limits = rev(levels(p$explanatory)), 
      labels = explanatory_labels) +
    scale_colour_manual(values = c(colour1, colour2, colour3, colour4, colour5, colour6), breaks = c('Realm', 'City geography', 'Regional (50km) geography', 'Regional (20km) geography', 'Spatial')) +
    theme_bw() +
    geom_vline(xintercept=0, linetype="dotted") +
    guides(colour=guide_legend(title="Predictor type")) + xlab('Difference in response from 0\nhabitat filtering (< 0) and competitive interactions (> 0)\n± Standard Error') + ylab('Predictor') +
    theme(legend.justification = "top")
}

MNTD

std_mntd_analysis_geo_plot = geom_map(geom_sf(data = analysis_data, aes(color = mntd_standard, geometry = geometry)), 'MNTD')
std_mntd_analysis_geo_plot

std_mntd_analysis_data = model_data(analysis_data[!is.na(analysis_data$mntd_standard),], 'mntd_standard')
std_mntd_analysis_predictors = std_mntd_analysis_data[,-1]
std_mntd_analysis_interp = VSURF(x = std_mntd_analysis_predictors, y = std_mntd_analysis_data$mntd_standard)
Thresholding step
Estimated computational time (on one core): 14 sec.

  |                                                                                                                                       
  |                                                                                                                                 |   0%
  |                                                                                                                                       
  |======                                                                                                                           |   5%
  |                                                                                                                                       
  |=============                                                                                                                    |  10%
  |                                                                                                                                       
  |===================                                                                                                              |  15%
  |                                                                                                                                       
  |==========================                                                                                                       |  20%
  |                                                                                                                                       
  |================================                                                                                                 |  25%
  |                                                                                                                                       
  |=======================================                                                                                          |  30%
  |                                                                                                                                       
  |=============================================                                                                                    |  35%
  |                                                                                                                                       
  |====================================================                                                                             |  40%
  |                                                                                                                                       
  |==========================================================                                                                       |  45%
  |                                                                                                                                       
  |================================================================                                                                 |  50%
  |                                                                                                                                       
  |=======================================================================                                                          |  55%
  |                                                                                                                                       
  |=============================================================================                                                    |  60%
  |                                                                                                                                       
  |====================================================================================                                             |  65%
  |                                                                                                                                       
  |==========================================================================================                                       |  70%
  |                                                                                                                                       
  |=================================================================================================                                |  75%
  |                                                                                                                                       
  |=======================================================================================================                          |  80%
  |                                                                                                                                       
  |==============================================================================================================                   |  85%
  |                                                                                                                                       
  |====================================================================================================================             |  90%
  |                                                                                                                                       
  |===========================================================================================================================      |  95%
  |                                                                                                                                       
  |=================================================================================================================================| 100%
Interpretation step (on 29 variables)
Estimated computational time (on one core): between 1.5 sec. and  28.4 sec.

  |                                                                                                                                       
  |                                                                                                                                 |   0%
  |                                                                                                                                       
  |====                                                                                                                             |   3%
  |                                                                                                                                       
  |=========                                                                                                                        |   7%
  |                                                                                                                                       
  |=============                                                                                                                    |  10%
  |                                                                                                                                       
  |==================                                                                                                               |  14%
  |                                                                                                                                       
  |======================                                                                                                           |  17%
  |                                                                                                                                       
  |===========================                                                                                                      |  21%
  |                                                                                                                                       
  |===============================                                                                                                  |  24%
  |                                                                                                                                       
  |====================================                                                                                             |  28%
  |                                                                                                                                       
  |========================================                                                                                         |  31%
  |                                                                                                                                       
  |============================================                                                                                     |  34%
  |                                                                                                                                       
  |=================================================                                                                                |  38%
  |                                                                                                                                       
  |=====================================================                                                                            |  41%
  |                                                                                                                                       
  |==========================================================                                                                       |  45%
  |                                                                                                                                       
  |==============================================================                                                                   |  48%
  |                                                                                                                                       
  |===================================================================                                                              |  52%
  |                                                                                                                                       
  |=======================================================================                                                          |  55%
  |                                                                                                                                       
  |============================================================================                                                     |  59%
  |                                                                                                                                       
  |================================================================================                                                 |  62%
  |                                                                                                                                       
  |=====================================================================================                                            |  66%
  |                                                                                                                                       
  |=========================================================================================                                        |  69%
  |                                                                                                                                       
  |=============================================================================================                                    |  72%
  |                                                                                                                                       
  |==================================================================================================                               |  76%
  |                                                                                                                                       
  |======================================================================================================                           |  79%
  |                                                                                                                                       
  |===========================================================================================================                      |  83%
  |                                                                                                                                       
  |===============================================================================================================                  |  86%
  |                                                                                                                                       
  |====================================================================================================================             |  90%
  |                                                                                                                                       
  |========================================================================================================================         |  93%
  |                                                                                                                                       
  |=============================================================================================================================    |  97%
  |                                                                                                                                       
  |=================================================================================================================================| 100%
Prediction step (on 11 variables)
Maximum estimated computational time (on one core): 4.2 sec.

  |                                                                                                                                       
  |                                                                                                                                 |   0%
  |                                                                                                                                       
  |============                                                                                                                     |   9%
  |                                                                                                                                       
  |=======================                                                                                                          |  18%
  |                                                                                                                                       
  |===================================                                                                                              |  27%
  |                                                                                                                                       
  |===============================================                                                                                  |  36%
  |                                                                                                                                       
  |===========================================================                                                                      |  45%
  |                                                                                                                                       
  |======================================================================                                                           |  55%
  |                                                                                                                                       
  |==================================================================================                                               |  64%
  |                                                                                                                                       
  |==============================================================================================                                   |  73%
  |                                                                                                                                       
  |==========================================================================================================                       |  82%
  |                                                                                                                                       
  |=====================================================================================================================            |  91%
  |                                                                                                                                       
  |=================================================================================================================================| 100%
names(std_mntd_analysis_predictors[,std_mntd_analysis_interp$varselect.interp])
 [1] "core_realm"                    "longitude"                     "city_avg_max_monthly_temp"     "city_avg_temp"                
 [5] "abs_latitude"                  "city_avg_max_monthly_rainfall" "city_avg_monthly_temp"         "city_avg_min_monthly_temp"    
 [9] "city_avg_ndvi"                 "city_avg_rainfall"             "city_max_elev"                
std_mntd_analysis_formula = formula_from_vsurp(std_mntd_analysis_predictors, "mntd_standard", std_mntd_analysis_interp)
std_mntd_analysis_result <- model_average(std_mntd_analysis_formula, std_mntd_analysis_data)
Fixed term is "(Intercept)"
std_mntd_analysis_result_table = model_summary(std_mntd_analysis_result)
std_mntd_analysis_result_table
std_mntd_analysis_pred_plot = plot_vsurp_result(std_mntd_analysis_result_table)
std_mntd_analysis_pred_plot

Gape width - FDiv

std_gape_fdiv_analysis_geo_plot = geom_map(geom_sf(data = analysis_data, aes(color = beak_width_fdiv_standard, geometry = geometry)), 'Beak Width FDiv')
std_gape_fdiv_analysis_geo_plot

std_gape_fdiv_analysis_data = model_data(analysis_data[!is.na(analysis_data$beak_width_fdiv_standard),], 'beak_width_fdiv_standard')
std_gape_fdiv_analysis_predictors = std_gape_fdiv_analysis_data[,-1]
std_gape_fdiv_analysis_interp = VSURF(x = std_gape_fdiv_analysis_predictors, y = std_gape_fdiv_analysis_data$beak_width_fdiv_standard)
Thresholding step
Estimated computational time (on one core): 13.3 sec.

  |                                                                                                                                       
  |                                                                                                                                 |   0%
  |                                                                                                                                       
  |======                                                                                                                           |   5%
  |                                                                                                                                       
  |=============                                                                                                                    |  10%
  |                                                                                                                                       
  |===================                                                                                                              |  15%
  |                                                                                                                                       
  |==========================                                                                                                       |  20%
  |                                                                                                                                       
  |================================                                                                                                 |  25%
  |                                                                                                                                       
  |=======================================                                                                                          |  30%
  |                                                                                                                                       
  |=============================================                                                                                    |  35%
  |                                                                                                                                       
  |====================================================                                                                             |  40%
  |                                                                                                                                       
  |==========================================================                                                                       |  45%
  |                                                                                                                                       
  |================================================================                                                                 |  50%
  |                                                                                                                                       
  |=======================================================================                                                          |  55%
  |                                                                                                                                       
  |=============================================================================                                                    |  60%
  |                                                                                                                                       
  |====================================================================================                                             |  65%
  |                                                                                                                                       
  |==========================================================================================                                       |  70%
  |                                                                                                                                       
  |=================================================================================================                                |  75%
  |                                                                                                                                       
  |=======================================================================================================                          |  80%
  |                                                                                                                                       
  |==============================================================================================================                   |  85%
  |                                                                                                                                       
  |====================================================================================================================             |  90%
  |                                                                                                                                       
  |===========================================================================================================================      |  95%
  |                                                                                                                                       
  |=================================================================================================================================| 100%
Interpretation step (on 29 variables)
Estimated computational time (on one core): between 5.5 sec. and  25.8 sec.

  |                                                                                                                                       
  |                                                                                                                                 |   0%
  |                                                                                                                                       
  |====                                                                                                                             |   3%
  |                                                                                                                                       
  |=========                                                                                                                        |   7%
  |                                                                                                                                       
  |=============                                                                                                                    |  10%
  |                                                                                                                                       
  |==================                                                                                                               |  14%
  |                                                                                                                                       
  |======================                                                                                                           |  17%
  |                                                                                                                                       
  |===========================                                                                                                      |  21%
  |                                                                                                                                       
  |===============================                                                                                                  |  24%
  |                                                                                                                                       
  |====================================                                                                                             |  28%
  |                                                                                                                                       
  |========================================                                                                                         |  31%
  |                                                                                                                                       
  |============================================                                                                                     |  34%
  |                                                                                                                                       
  |=================================================                                                                                |  38%
  |                                                                                                                                       
  |=====================================================                                                                            |  41%
  |                                                                                                                                       
  |==========================================================                                                                       |  45%
  |                                                                                                                                       
  |==============================================================                                                                   |  48%
  |                                                                                                                                       
  |===================================================================                                                              |  52%
  |                                                                                                                                       
  |=======================================================================                                                          |  55%
  |                                                                                                                                       
  |============================================================================                                                     |  59%
  |                                                                                                                                       
  |================================================================================                                                 |  62%
  |                                                                                                                                       
  |=====================================================================================                                            |  66%
  |                                                                                                                                       
  |=========================================================================================                                        |  69%
  |                                                                                                                                       
  |=============================================================================================                                    |  72%
  |                                                                                                                                       
  |==================================================================================================                               |  76%
  |                                                                                                                                       
  |======================================================================================================                           |  79%
  |                                                                                                                                       
  |===========================================================================================================                      |  83%
  |                                                                                                                                       
  |===============================================================================================================                  |  86%
  |                                                                                                                                       
  |====================================================================================================================             |  90%
  |                                                                                                                                       
  |========================================================================================================================         |  93%
  |                                                                                                                                       
  |=============================================================================================================================    |  97%
  |                                                                                                                                       
  |=================================================================================================================================| 100%
Prediction step (on 11 variables)
Maximum estimated computational time (on one core): 4.2 sec.

  |                                                                                                                                       
  |                                                                                                                                 |   0%
  |                                                                                                                                       
  |============                                                                                                                     |   9%
  |                                                                                                                                       
  |=======================                                                                                                          |  18%
  |                                                                                                                                       
  |===================================                                                                                              |  27%
  |                                                                                                                                       
  |===============================================                                                                                  |  36%
  |                                                                                                                                       
  |===========================================================                                                                      |  45%
  |                                                                                                                                       
  |======================================================================                                                           |  55%
  |                                                                                                                                       
  |==================================================================================                                               |  64%
  |                                                                                                                                       
  |==============================================================================================                                   |  73%
  |                                                                                                                                       
  |==========================================================================================================                       |  82%
  |                                                                                                                                       
  |=====================================================================================================================            |  91%
  |                                                                                                                                       
  |=================================================================================================================================| 100%
names(std_gape_fdiv_analysis_predictors[,std_gape_fdiv_analysis_interp$varselect.interp])
 [1] "abs_latitude"                  "core_realm"                    "longitude"                     "city_avg_max_monthly_temp"    
 [5] "city_avg_min_monthly_temp"     "city_avg_temp"                 "city_avg_max_monthly_rainfall" "city_avg_monthly_temp"        
 [9] "city_avg_min_monthly_rainfall" "city_max_elev"                 "region_50km_max_elev"         
std_gape_fdiv_analysis_formula = formula_from_vsurp(std_gape_fdiv_analysis_predictors, "beak_width_fdiv_standard", std_gape_fdiv_analysis_interp)
std_gape_fdiv_analysis_result <- model_average(std_gape_fdiv_analysis_formula, std_gape_fdiv_analysis_data)
Fixed term is "(Intercept)"
std_gape_fdiv_analysis_result_table = model_summary(std_gape_fdiv_analysis_result)
std_gape_fdiv_analysis_result_table
std_gape_fdiv_analysis_pred_plot = plot_vsurp_result(std_gape_fdiv_analysis_result_table)
std_gape_fdiv_analysis_pred_plot

HWI - FDiv

std_hwi_fdiv_analysis_geo_plot = geom_map(geom_sf(data = analysis_data, aes(color = hwi_fdiv_standard, geometry = geometry)), 'HWI FDiv')
std_hwi_fdiv_analysis_geo_plot

std_hwi_fdiv_analysis_data = model_data(analysis_data[!is.na(analysis_data$hwi_fdiv_standard),], 'hwi_fdiv_standard')
std_hwi_fdiv_analysis_predictors = std_hwi_fdiv_analysis_data[,-1]
std_hwi_fdiv_analysis_interp = VSURF(x = std_hwi_fdiv_analysis_predictors, y = std_hwi_fdiv_analysis_data$hwi_fdiv_standard)
Thresholding step
Estimated computational time (on one core): 13.1 sec.

  |                                                                                                                                       
  |                                                                                                                                 |   0%
  |                                                                                                                                       
  |======                                                                                                                           |   5%
  |                                                                                                                                       
  |=============                                                                                                                    |  10%
  |                                                                                                                                       
  |===================                                                                                                              |  15%
  |                                                                                                                                       
  |==========================                                                                                                       |  20%
  |                                                                                                                                       
  |================================                                                                                                 |  25%
  |                                                                                                                                       
  |=======================================                                                                                          |  30%
  |                                                                                                                                       
  |=============================================                                                                                    |  35%
  |                                                                                                                                       
  |====================================================                                                                             |  40%
  |                                                                                                                                       
  |==========================================================                                                                       |  45%
  |                                                                                                                                       
  |================================================================                                                                 |  50%
  |                                                                                                                                       
  |=======================================================================                                                          |  55%
  |                                                                                                                                       
  |=============================================================================                                                    |  60%
  |                                                                                                                                       
  |====================================================================================                                             |  65%
  |                                                                                                                                       
  |==========================================================================================                                       |  70%
  |                                                                                                                                       
  |=================================================================================================                                |  75%
  |                                                                                                                                       
  |=======================================================================================================                          |  80%
  |                                                                                                                                       
  |==============================================================================================================                   |  85%
  |                                                                                                                                       
  |====================================================================================================================             |  90%
  |                                                                                                                                       
  |===========================================================================================================================      |  95%
  |                                                                                                                                       
  |=================================================================================================================================| 100%
Interpretation step (on 29 variables)
Estimated computational time (on one core): between 1.5 sec. and  26.1 sec.

  |                                                                                                                                       
  |                                                                                                                                 |   0%
  |                                                                                                                                       
  |====                                                                                                                             |   3%
  |                                                                                                                                       
  |=========                                                                                                                        |   7%
  |                                                                                                                                       
  |=============                                                                                                                    |  10%
  |                                                                                                                                       
  |==================                                                                                                               |  14%
  |                                                                                                                                       
  |======================                                                                                                           |  17%
  |                                                                                                                                       
  |===========================                                                                                                      |  21%
  |                                                                                                                                       
  |===============================                                                                                                  |  24%
  |                                                                                                                                       
  |====================================                                                                                             |  28%
  |                                                                                                                                       
  |========================================                                                                                         |  31%
  |                                                                                                                                       
  |============================================                                                                                     |  34%
  |                                                                                                                                       
  |=================================================                                                                                |  38%
  |                                                                                                                                       
  |=====================================================                                                                            |  41%
  |                                                                                                                                       
  |==========================================================                                                                       |  45%
  |                                                                                                                                       
  |==============================================================                                                                   |  48%
  |                                                                                                                                       
  |===================================================================                                                              |  52%
  |                                                                                                                                       
  |=======================================================================                                                          |  55%
  |                                                                                                                                       
  |============================================================================                                                     |  59%
  |                                                                                                                                       
  |================================================================================                                                 |  62%
  |                                                                                                                                       
  |=====================================================================================                                            |  66%
  |                                                                                                                                       
  |=========================================================================================                                        |  69%
  |                                                                                                                                       
  |=============================================================================================                                    |  72%
  |                                                                                                                                       
  |==================================================================================================                               |  76%
  |                                                                                                                                       
  |======================================================================================================                           |  79%
  |                                                                                                                                       
  |===========================================================================================================                      |  83%
  |                                                                                                                                       
  |===============================================================================================================                  |  86%
  |                                                                                                                                       
  |====================================================================================================================             |  90%
  |                                                                                                                                       
  |========================================================================================================================         |  93%
  |                                                                                                                                       
  |=============================================================================================================================    |  97%
  |                                                                                                                                       
  |=================================================================================================================================| 100%
Prediction step (on 6 variables)
Maximum estimated computational time (on one core): 1.8 sec.

  |                                                                                                                                       
  |                                                                                                                                 |   0%
  |                                                                                                                                       
  |======================                                                                                                           |  17%
  |                                                                                                                                       
  |===========================================                                                                                      |  33%
  |                                                                                                                                       
  |================================================================                                                                 |  50%
  |                                                                                                                                       
  |======================================================================================                                           |  67%
  |                                                                                                                                       
  |============================================================================================================                     |  83%
  |                                                                                                                                       
  |=================================================================================================================================| 100%
names(std_hwi_fdiv_analysis_predictors[,std_hwi_fdiv_analysis_interp$varselect.interp])
[1] "core_realm"                "city_avg_temp"             "city_avg_max_monthly_temp" "region_50km_min_elev"     
[5] "longitude"                 "abs_latitude"             
std_hwi_fdiv_analysis_formula = formula_from_vsurp(std_hwi_fdiv_analysis_predictors, "hwi_fdiv_standard", std_hwi_fdiv_analysis_interp)
std_hwi_fdiv_analysis_result <- model_average(std_hwi_fdiv_analysis_formula, std_hwi_fdiv_analysis_data)
Fixed term is "(Intercept)"
std_hwi_fdiv_analysis_result_table = model_summary(std_hwi_fdiv_analysis_result)
std_hwi_fdiv_analysis_result_table
std_hwi_fdiv_analysis_pred_plot = plot_vsurp_result(std_hwi_fdiv_analysis_result_table)
std_hwi_fdiv_analysis_pred_plot

Mass - FDiv

std_mass_fdiv_analysis_geo_plot = geom_map(geom_sf(data = analysis_data, aes(color = mass_fdiv_standard, geometry = geometry)), 'Mass FDiv')
std_mass_fdiv_analysis_geo_plot

std_mass_fdiv_analysis_data = model_data(analysis_data[!is.na(analysis_data$mass_fdiv_standard),], 'mass_fdiv_standard')
std_mass_fdiv_analysis_predictors = std_mass_fdiv_analysis_data[,-1]
std_mass_fdiv_analysis_interp = VSURF(x = std_mass_fdiv_analysis_predictors, y = std_mass_fdiv_analysis_data$mass_fdiv_standard)
Thresholding step
Estimated computational time (on one core): 13.2 sec.

  |                                                                                                                                       
  |                                                                                                                                 |   0%
  |                                                                                                                                       
  |======                                                                                                                           |   5%
  |                                                                                                                                       
  |=============                                                                                                                    |  10%
  |                                                                                                                                       
  |===================                                                                                                              |  15%
  |                                                                                                                                       
  |==========================                                                                                                       |  20%
  |                                                                                                                                       
  |================================                                                                                                 |  25%
  |                                                                                                                                       
  |=======================================                                                                                          |  30%
  |                                                                                                                                       
  |=============================================                                                                                    |  35%
  |                                                                                                                                       
  |====================================================                                                                             |  40%
  |                                                                                                                                       
  |==========================================================                                                                       |  45%
  |                                                                                                                                       
  |================================================================                                                                 |  50%
  |                                                                                                                                       
  |=======================================================================                                                          |  55%
  |                                                                                                                                       
  |=============================================================================                                                    |  60%
  |                                                                                                                                       
  |====================================================================================                                             |  65%
  |                                                                                                                                       
  |==========================================================================================                                       |  70%
  |                                                                                                                                       
  |=================================================================================================                                |  75%
  |                                                                                                                                       
  |=======================================================================================================                          |  80%
  |                                                                                                                                       
  |==============================================================================================================                   |  85%
  |                                                                                                                                       
  |====================================================================================================================             |  90%
  |                                                                                                                                       
  |===========================================================================================================================      |  95%
  |                                                                                                                                       
  |=================================================================================================================================| 100%
Interpretation step (on 29 variables)
Estimated computational time (on one core): between 1.2 sec. and  25.8 sec.

  |                                                                                                                                       
  |                                                                                                                                 |   0%
  |                                                                                                                                       
  |====                                                                                                                             |   3%
  |                                                                                                                                       
  |=========                                                                                                                        |   7%
  |                                                                                                                                       
  |=============                                                                                                                    |  10%
  |                                                                                                                                       
  |==================                                                                                                               |  14%
  |                                                                                                                                       
  |======================                                                                                                           |  17%
  |                                                                                                                                       
  |===========================                                                                                                      |  21%
  |                                                                                                                                       
  |===============================                                                                                                  |  24%
  |                                                                                                                                       
  |====================================                                                                                             |  28%
  |                                                                                                                                       
  |========================================                                                                                         |  31%
  |                                                                                                                                       
  |============================================                                                                                     |  34%
  |                                                                                                                                       
  |=================================================                                                                                |  38%
  |                                                                                                                                       
  |=====================================================                                                                            |  41%
  |                                                                                                                                       
  |==========================================================                                                                       |  45%
  |                                                                                                                                       
  |==============================================================                                                                   |  48%
  |                                                                                                                                       
  |===================================================================                                                              |  52%
  |                                                                                                                                       
  |=======================================================================                                                          |  55%
  |                                                                                                                                       
  |============================================================================                                                     |  59%
  |                                                                                                                                       
  |================================================================================                                                 |  62%
  |                                                                                                                                       
  |=====================================================================================                                            |  66%
  |                                                                                                                                       
  |=========================================================================================                                        |  69%
  |                                                                                                                                       
  |=============================================================================================                                    |  72%
  |                                                                                                                                       
  |==================================================================================================                               |  76%
  |                                                                                                                                       
  |======================================================================================================                           |  79%
  |                                                                                                                                       
  |===========================================================================================================                      |  83%
  |                                                                                                                                       
  |===============================================================================================================                  |  86%
  |                                                                                                                                       
  |====================================================================================================================             |  90%
  |                                                                                                                                       
  |========================================================================================================================         |  93%
  |                                                                                                                                       
  |=============================================================================================================================    |  97%
  |                                                                                                                                       
  |=================================================================================================================================| 100%
Prediction step (on 7 variables)
Maximum estimated computational time (on one core): 2.1 sec.

  |                                                                                                                                       
  |                                                                                                                                 |   0%
  |                                                                                                                                       
  |==================                                                                                                               |  14%
  |                                                                                                                                       
  |=====================================                                                                                            |  29%
  |                                                                                                                                       
  |=======================================================                                                                          |  43%
  |                                                                                                                                       
  |==========================================================================                                                       |  57%
  |                                                                                                                                       
  |============================================================================================                                     |  71%
  |                                                                                                                                       
  |===============================================================================================================                  |  86%
  |                                                                                                                                       
  |=================================================================================================================================| 100%
names(std_mass_fdiv_analysis_predictors[,std_mass_fdiv_analysis_interp$varselect.interp])
[1] "core_realm"                "abs_latitude"              "city_avg_temp"             "city_avg_min_monthly_temp"
[5] "city_avg_max_monthly_temp" "city_avg_ndvi"             "city_avg_rainfall"        
std_mass_fdiv_analysis_formula = formula_from_vsurp(std_mass_fdiv_analysis_predictors, "mass_fdiv_standard", std_mass_fdiv_analysis_interp)
std_mass_fdiv_analysis_result <- model_average(std_mass_fdiv_analysis_formula, std_mass_fdiv_analysis_data)
Fixed term is "(Intercept)"
std_mass_fdiv_analysis_result_table = model_summary(std_mass_fdiv_analysis_result)
std_mass_fdiv_analysis_result_table
std_mass_fdiv_analysis_pred_plot = plot_vsurp_result(std_mass_fdiv_analysis_result_table)
std_mass_fdiv_analysis_pred_plot

Create plot of differences in process response

pred_legend <- ggpubr::get_legend(
  # create some space to the left of the legend
  std_hwi_fdiv_analysis_pred_plot + theme(legend.box.margin = margin(0, 0, 0, 0)) + guides(colour=guide_legend(ncol=2)) + labs(color = "Predictor type")
)
`geom_line()`: Each group consists of only one observation.
ℹ Do you need to adjust the group aesthetic?
geo_legend <- ggpubr::get_legend(
  # create some space to the left of the legend
  std_mass_fdiv_analysis_geo_plot + theme(legend.box.margin = margin(-80, 0, 0, 12), legend.title.position = "top", legend.key.width = unit(10, 'mm')) + labs(color = "Standardised response")
)

legend = plot_grid(
  geo_legend,
  pred_legend, 
  nrow = 1
)
legend

plot_grid(
  plot_grid(
    std_mntd_analysis_geo_plot + theme(legend.position="none"), 
    std_mntd_analysis_pred_plot + theme(legend.position="none") + scale_x_continuous(name = '', limits = c(-3, 3)) + ylab(''), 
    nrow = 1
  ) + draw_label("MNTD", size = 16, angle = 90, x = 0.01, y = 0.5),
  plot_grid(
    std_gape_fdiv_analysis_geo_plot + theme(legend.position="none"), 
    std_gape_fdiv_analysis_pred_plot + theme(legend.position="none") + scale_x_continuous(name = '', limits = c(-3, 3)) + ylab(''), 
    nrow = 1
  ) + draw_label("Beak Width", size = 16, angle = 90, x = 0.01, y = 0.5),
  plot_grid(
    std_hwi_fdiv_analysis_geo_plot + theme(legend.position="none"), 
    std_hwi_fdiv_analysis_pred_plot + theme(legend.position="none") + scale_x_continuous(name = '', limits = c(-3, 3)) + ylab(''), 
    nrow = 1
  ) + draw_label("HWI", size = 16, angle = 90, x = 0.01, y = 0.5),
  plot_grid(
    std_mass_fdiv_analysis_geo_plot + theme(legend.position="none"), 
    std_mass_fdiv_analysis_pred_plot + theme(legend.position="none") + scale_x_continuous(name = '', limits = c(-3, 3)) + ylab(''), 
    nrow = 1
  ) + draw_label("Mass", size = 16, angle = 90, x = 0.01, y = 0.5), 
  legend,
  nrow = 5
)
`geom_line()`: Each group consists of only one observation.
ℹ Do you need to adjust the group aesthetic?`geom_line()`: Each group consists of only one observation.
ℹ Do you need to adjust the group aesthetic?`geom_line()`: Each group consists of only one observation.
ℹ Do you need to adjust the group aesthetic?`geom_line()`: Each group consists of only one observation.
ℹ Do you need to adjust the group aesthetic?
ggsave(filename(FIGURES_OUTPUT_DIR, 'process_response.jpg'), width = 3000, height = 3200, units = 'px')

Compare metrics against each other

ggplot(analysis_data, aes(x = beak_width_fdiv_standard, y = mntd_standard, colour = core_realm)) + 
  geom_point() +
  ylab("MNTD") + 
  xlab("Beak Width FDiv") +
  theme_bw() + labs(color = "Realm")

ggplot(analysis_data, aes(x = hwi_fdiv_standard, y = mntd_standard, colour = core_realm)) + 
  geom_point() +
  ylab("MNTD") + 
  xlab("HWI FDiv") +
  theme_bw() + labs(color = "Realm")

ggplot(analysis_data, aes(x = hwi_fdiv_standard, y = beak_width_fdiv_standard, colour = core_realm)) + 
  geom_point() +
  ylab("Beak Width FDiv") + 
  xlab("HWI FDiv") +
  theme_bw() + labs(color = "Realm")

mntd_fdiv_analysis = analysis_data %>% 
  dplyr::select(city_id,  mntd_standard, hwi_fdiv_standard, beak_width_fdiv_standard, mass_fdiv_standard) %>%
  left_join(community_summary) %>%
  mutate(urban_pool_perc = urban_pool_size * 100 / regional_pool_size)
Joining with `by = join_by(city_id)`
mntd_fdiv_analysis
ggpairs(mntd_fdiv_analysis %>% dplyr::select(mntd_standard, hwi_fdiv_standard, beak_width_fdiv_standard, mass_fdiv_standard, regional_pool_size, urban_pool_size, urban_pool_perc), columnLabels = c('MNTD', 'HWI FD', 'Bk FD', 'Mss FD', 'Region Rich.', 'Urban Rich.', '% Urban'))
ggsave(filename(FIGURES_OUTPUT_DIR, 'appendix_standarised_correlation.jpg'))
Saving 7.29 x 4.51 in image

LS0tCnRpdGxlOiAiTWV0cmljcyBmb3IgYXNzZXNzaW5nIGNvbW11bml0eSBhc3NlbWJseSBwcm9jZXNzZXMiCm91dHB1dDogaHRtbF9ub3RlYm9vawpiaWJsaW9ncmFwaHk6IC4uL3JlZi5iaWIgIAotLS0KCmBgYHtyfQpzb3VyY2UoJy4uL2Vudi5SJykKYGBgCgpgYGB7cn0KY29tbXVuaXR5X2RhdGEgPSByZWFkX2NzdihmaWxlbmFtZShDT01NVU5JVFlfT1VUUFVUX0RJUiwgJ2NvbW11bml0eV9hc3NlbWJseV9tZXRyaWNzX3VzaW5nX3JlbGF0aXZlX2FidW5kYW5jZS5jc3YnKSkKaGVhZChjb21tdW5pdHlfZGF0YSkKY29sbmFtZXMoY29tbXVuaXR5X2RhdGEpCmBgYApgYGB7cn0KbWluKGNvbW11bml0eV9kYXRhJG1udGRfc3RhbmRhcmQpCm1heChjb21tdW5pdHlfZGF0YSRtbnRkX3N0YW5kYXJkKQptaW4oY29tbXVuaXR5X2RhdGEkYmVha193aWR0aF9mZGl2X3N0YW5kYXJkKQptYXgoY29tbXVuaXR5X2RhdGEkYmVha193aWR0aF9mZGl2X3N0YW5kYXJkKQptaW4oY29tbXVuaXR5X2RhdGEkaHdpX2ZkaXZfc3RhbmRhcmQpCm1heChjb21tdW5pdHlfZGF0YSRod2lfZmRpdl9zdGFuZGFyZCkKbWluKGNvbW11bml0eV9kYXRhJG1hc3NfZmRpdl9zdGFuZGFyZCkKbWF4KGNvbW11bml0eV9kYXRhJG1hc3NfZmRpdl9zdGFuZGFyZCkKYGBgCgoKSm9pbiBvbiByZWFsbXMKYGBge3J9CmNpdHlfdG9fcmVhbG0gPSByZWFkX2NzdihmaWxlbmFtZShDSVRZX0RBVEFfT1VUUFVUX0RJUiwgJ3JlYWxtcy5jc3YnKSkKY29tbXVuaXR5X2RhdGFfd2l0aF9yZWFsbSA9IGxlZnRfam9pbihjb21tdW5pdHlfZGF0YSwgY2l0eV90b19yZWFsbSkKYGBgCgpDaXRpZXMgYXMgcG9pbnRzCmBgYHtyfQpjaXR5X3BvaW50cyA9IHN0X2NlbnRyb2lkKHJlYWRfc2YoZmlsZW5hbWUoQ0lUWV9EQVRBX09VVFBVVF9ESVIsICdjaXR5X3NlbGVjdGlvbi5zaHAnKSkpICU+JSBsZWZ0X2pvaW4oY29tbXVuaXR5X2RhdGFfd2l0aF9yZWFsbSkKY2l0eV9wb2ludHNfY29vcmRzID0gc3RfY29vcmRpbmF0ZXMoY2l0eV9wb2ludHMpCmNpdHlfcG9pbnRzJGxhdGl0dWRlID0gY2l0eV9wb2ludHNfY29vcmRzWywxXQpjaXR5X3BvaW50cyRsb25naXR1ZGUgPSBjaXR5X3BvaW50c19jb29yZHNbLDJdCmBgYAogIApgYGB7cn0Kd29ybGRfbWFwID0gcmVhZF9jb3VudHJ5X2JvdW5kYXJpZXMoKQpgYGAKCkxvYWQgY29tbXVuaXR5IGRhdGEsIGFuZCBjcmVhdGUgbG9uZyBmb3JtYXQgdmVyc2lvbgpgYGB7cn0KY29tbXVuaXRpZXMgPSByZWFkX2NzdihmaWxlbmFtZShDT01NVU5JVFlfT1VUUFVUX0RJUiwgJ2NvbW11bml0aWVzX2Zvcl9hbmFseXNpcy5jc3YnKSkKY29tbXVuaXRpZXMKYGBgCgpgYGB7cn0KY29tbXVuaXR5X3N1bW1hcnkgPSBjb21tdW5pdGllcyAlPiUgZ3JvdXBfYnkoY2l0eV9pZCkgJT4lIHN1bW1hcmlzZShyZWdpb25hbF9wb29sX3NpemUgPSBuKCksIHVyYmFuX3Bvb2xfc2l6ZSA9IHN1bShyZWxhdGl2ZV9hYnVuZGFuY2VfcHJveHkgPiAwKSkKY29tbXVuaXR5X3N1bW1hcnkKYGBgCgpMb2FkIHRyYWl0IGRhdGEKYGBge3J9CnRyYWl0cyA9IHJlYWRfY3N2KGZpbGVuYW1lKFRBWE9OT01ZX09VVFBVVF9ESVIsICd0cmFpdHNfZWJpcmQuY3N2JykpCmhlYWQodHJhaXRzKQpgYGAKCkxvYWQgcmVhbG0gZ2VvCmBgYHtyfQpyZXNvbHZlID0gcmVhZF9yZXNvbHZlKCkKaGVhZChyZXNvbHZlKQpgYGAKCiMgU3VtbWFyeSBtZXRyaWNzIGJ5IFJlYWxtCmBgYHtyfQp0ZXN0X3JlcXVpcmVkX3ZhbHVlcyA9IGZ1bmN0aW9uKG5hbWUsIGRmKSB7CiAgY2F0KHBhc3RlKAogICAgdGVzdF92YWx1ZV93aWxjb3gocGFzdGUobmFtZSwgJ01OVEQnKSwgZGYkbW50ZF9zdGFuZGFyZCksCiAgICB0ZXN0X3ZhbHVlX3dpbGNveChwYXN0ZShuYW1lLCAnQmVhayBHYXBlIEZEaXYnKSwgZGYkYmVha193aWR0aF9mZGl2X3N0YW5kYXJkKSwKICAgIHRlc3RfdmFsdWVfd2lsY294KHBhc3RlKG5hbWUsICdIV0kgRkRpdicpLCBkZiRod2lfZmRpdl9zdGFuZGFyZCksCiAgICB0ZXN0X3ZhbHVlX3dpbGNveChwYXN0ZShuYW1lLCAnTWFzcyBGRGl2JyksIGRmJG1hc3NfZmRpdl9zdGFuZGFyZCksCiAgICBwYXN0ZSgnTicsIG5yb3coZGYpKSwKICAgIHNlcCA9ICJcbiIpKQp9CmBgYAoKYGBge3J9CnRlc3RfcmVxdWlyZWRfdmFsdWVzKCdHbG9iYWwnLCBjb21tdW5pdHlfZGF0YV93aXRoX3JlYWxtKQpgYGAKCmBgYHtyfQp1bmlxdWUoY29tbXVuaXR5X2RhdGFfd2l0aF9yZWFsbSRjb3JlX3JlYWxtKQpgYGAKCmBgYHtyfQp0ZXN0X3JlcXVpcmVkX3ZhbHVlcygnTmVhcmN0aWMnLCBjb21tdW5pdHlfZGF0YV93aXRoX3JlYWxtW2NvbW11bml0eV9kYXRhX3dpdGhfcmVhbG0kY29yZV9yZWFsbSA9PSAnTmVhcmN0aWMnLF0pCmBgYAoKYGBge3J9CnRlc3RfcmVxdWlyZWRfdmFsdWVzKCdOZW90cm9waWMnLCBjb21tdW5pdHlfZGF0YV93aXRoX3JlYWxtW2NvbW11bml0eV9kYXRhX3dpdGhfcmVhbG0kY29yZV9yZWFsbSA9PSAnTmVvdHJvcGljJyxdKQpgYGAKCmBgYHtyfQp0ZXN0X3JlcXVpcmVkX3ZhbHVlcygnUGFsZWFyY3RpYycsIGNvbW11bml0eV9kYXRhX3dpdGhfcmVhbG1bY29tbXVuaXR5X2RhdGFfd2l0aF9yZWFsbSRjb3JlX3JlYWxtID09ICdQYWxlYXJjdGljJyxdKQpgYGAKCmBgYHtyfQp0ZXN0X3JlcXVpcmVkX3ZhbHVlcygnQWZyb3Ryb3BpYycsIGNvbW11bml0eV9kYXRhX3dpdGhfcmVhbG1bY29tbXVuaXR5X2RhdGFfd2l0aF9yZWFsbSRjb3JlX3JlYWxtID09ICdBZnJvdHJvcGljJyxdKQpgYGAKCmBgYHtyfQp0ZXN0X3JlcXVpcmVkX3ZhbHVlcygnSW5kb21hbGF5YW4nLCBjb21tdW5pdHlfZGF0YV93aXRoX3JlYWxtW2NvbW11bml0eV9kYXRhX3dpdGhfcmVhbG0kY29yZV9yZWFsbSA9PSAnSW5kb21hbGF5YW4nLF0pCmBgYAoKYGBge3J9CnRlc3RfcmVxdWlyZWRfdmFsdWVzKCdBdXN0cmFsYXNpYScsIGNvbW11bml0eV9kYXRhX3dpdGhfcmVhbG1bY29tbXVuaXR5X2RhdGFfd2l0aF9yZWFsbSRjb3JlX3JlYWxtID09ICdBdXN0cmFsYXNpYScsXSkKYGBgCgojIFdoYXQgZmFtaWxpZXMgZXhpc3QgaW4gd2hpY2ggcmVhbG1zPwpgYGB7cn0KY29tbXVuaXRpZXMgJT4lIAogIGxlZnRfam9pbihjaXR5X3RvX3JlYWxtKSAlPiUgCiAgbXV0YXRlKGZhbWlseSA9IGdzdWIoICJfLiokIiwgIiIsIGViaXJkX3NwZWNpZXNfbmFtZSkpICU+JQogIGRwbHlyOjpzZWxlY3QoZmFtaWx5LCBjb3JlX3JlYWxtKSAlPiUKICBkaXN0aW5jdCgpICU+JQogIGFycmFuZ2UoY29yZV9yZWFsbSkKYGBgCgojIFN1bW1hcnkgbWV0cmljcyBieSBpbnRyb2R1Y2VkIHNwZWNpZXMKYGBge3J9CmNvbW11bml0aWVzID0gcmVhZF9jc3YoZmlsZW5hbWUoQ09NTVVOSVRZX09VVFBVVF9ESVIsICdjb21tdW5pdGllc19mb3JfYW5hbHlzaXMuY3N2JykpCmNpdHlfaW50cm9kdWNlZF9zcGVjaWVzID0gY29tbXVuaXRpZXMgJT4lIGdyb3VwX2J5KGNpdHlfaWQpICU+JSBzdW1tYXJpc2UobnVtYmVyX29mX3NwZWNpZXMgPSBuKCkpICU+JSBsZWZ0X2pvaW4oCiAgY29tbXVuaXRpZXMgJT4lIGdyb3VwX2J5KGNpdHlfaWQpICU+JSBmaWx0ZXIob3JpZ2luID09ICdJbnRyb2R1Y2VkJykgJT4lIHN1bW1hcmlzZShudW1iZXJfb2ZfaW50cm9kdWNlZF9zcGVjaWVzID0gbigpKQopICU+JSByZXBsYWNlX25hKGxpc3QobnVtYmVyX29mX2ludHJvZHVjZWRfc3BlY2llcyA9IDApKQoKY29tbXVuaXR5X2RhdGFfd2l0aF9pbnRyb2R1Y3Rpb25zID0gbGVmdF9qb2luKGNvbW11bml0eV9kYXRhLCBjaXR5X2ludHJvZHVjZWRfc3BlY2llcykKY29tbXVuaXR5X2RhdGFfd2l0aF9pbnRyb2R1Y3Rpb25zJGhhc19pbnRyb2R1Y2VkX3NwZWNpZXMgPSBjb21tdW5pdHlfZGF0YV93aXRoX2ludHJvZHVjdGlvbnMkbnVtYmVyX29mX2ludHJvZHVjZWRfc3BlY2llcyA+IDAKY29tbXVuaXR5X2RhdGFfd2l0aF9pbnRyb2R1Y3Rpb25zCmBgYAoKYGBge3J9CmNvbW11bml0eV9kYXRhX3dpdGhfaW50cm9kdWN0aW9uc1ssYygnbW50ZF9zdGFuZGFyZCcsICdoYXNfaW50cm9kdWNlZF9zcGVjaWVzJyldCmBgYAoKYGBge3J9CmNvbW11bml0eV9kYXRhX3dpdGhfaW50cm9kdWN0aW9ucyAlPiUgZ3JvdXBfYnkoaGFzX2ludHJvZHVjZWRfc3BlY2llcykgJT4lIHN1bW1hcmlzZSgKICB0b3RhbF9jaXRpZXMgPSBuKCksIAogIAogIG1lYW5fbW50ZF9zdGQgPSBtZWFuKG1udGRfc3RhbmRhcmQsIG5hLnJtID0gVCksCiAgbWVkaWFuX21udGRfc3RkID0gbWVkaWFuKG1udGRfc3RhbmRhcmQsIG5hLnJtID0gVCksCiAgc2RfbW50ZF9zdGQgPSBzZChtbnRkX3N0YW5kYXJkLCBuYS5ybSA9IFQpLAogIAogIG1lYW5fbWFzc19mZGl2X3N0ZCA9IG1lYW4obWFzc19mZGl2X3N0YW5kYXJkLCBuYS5ybSA9IFQpLAogIG1lZGlhbl9tYXNzX2ZkaXZfc3RkID0gbWVkaWFuKG1hc3NfZmRpdl9zdGFuZGFyZCwgbmEucm0gPSBUKSwKICBzZF9tYXNzX2ZkaXZfc3RkID0gc2QobWFzc19mZGl2X3N0YW5kYXJkLCBuYS5ybSA9IFQpLAogIAogIG1lYW5fZ2FwZV93aWR0aF9mZGl2X3N0ZCA9IG1lYW4oYmVha193aWR0aF9mZGl2X3N0YW5kYXJkLCBuYS5ybSA9IFQpLAogIG1lZGlhbl9nYXBlX3dpZHRoX2ZkaXZfc3RkID0gbWVkaWFuKGJlYWtfd2lkdGhfZmRpdl9zdGFuZGFyZCwgbmEucm0gPSBUKSwKICBzZF9nYXBlX3dpZHRoX2ZkaXZfc3RkID0gc2QoYmVha193aWR0aF9mZGl2X3N0YW5kYXJkLCBuYS5ybSA9IFQpLAogIAogIG1lYW5faGFuZHdpbmdfaW5kZXhfZmRpdl9zdGQgPSBtZWFuKGh3aV9mZGl2X3N0YW5kYXJkLCBuYS5ybSA9IFQpLAogIG1lZGlhbl9oYW5kd2luZ19pbmRleF9mZGl2X3N0ZCA9IG1lZGlhbihod2lfZmRpdl9zdGFuZGFyZCwgbmEucm0gPSBUKSwKICBzZF9oYW5kd2luZ19pbmRleF9mZGl2X3N0ZCA9IHNkKGh3aV9mZGl2X3N0YW5kYXJkLCBuYS5ybSA9IFQpCikKYGBgCgojIyBNTlRECmBgYHtyfQpnZ3Bsb3QoY29tbXVuaXR5X2RhdGFfd2l0aF9pbnRyb2R1Y3Rpb25zLCBhZXMoeCA9IGhhc19pbnRyb2R1Y2VkX3NwZWNpZXMsIHkgPSBtbnRkX3N0YW5kYXJkKSkgKyBnZW9tX2JveHBsb3QoKQpgYGAKCmBgYHtyfQp3aWxjb3gudGVzdChtbnRkX3N0YW5kYXJkIH4gaGFzX2ludHJvZHVjZWRfc3BlY2llcywgY29tbXVuaXR5X2RhdGFfd2l0aF9pbnRyb2R1Y3Rpb25zLCBuYS5hY3Rpb24gPSAnbmEub21pdCcpCmBgYAoKVGhlcmUgaXMgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHJlc3BvbnNlIG9mIGNpdGllcyB3aXRoIGludHJvZHVjZWQgc3BlY2llcyAoMC41M8KxMC4yNykgYW5kIHRob3NlIHdpdGhvdXQgKDAuNDfCsTAuMTkpIChwLXZhbHVlID0gMC4wMikuCgoKIyMgTWFzcyBGRGl2CmBgYHtyfQpnZ3Bsb3QoY29tbXVuaXR5X2RhdGFfd2l0aF9pbnRyb2R1Y3Rpb25zLCBhZXMoeCA9IGhhc19pbnRyb2R1Y2VkX3NwZWNpZXMsIHkgPSBtYXNzX2ZkaXZfc3RhbmRhcmQpKSArIGdlb21fYm94cGxvdCgpCmBgYAoKYGBge3J9CndpbGNveC50ZXN0KG1hc3NfZmRpdl9zdGFuZGFyZCB+IGhhc19pbnRyb2R1Y2VkX3NwZWNpZXMsIGNvbW11bml0eV9kYXRhX3dpdGhfaW50cm9kdWN0aW9ucywgbmEuYWN0aW9uID0gJ25hLm9taXQnKQpgYGAKVGhlcmUgaXMgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHJlc3BvbnNlIG9mIGNpdGllcyB3aXRoIGludHJvZHVjZWQgc3BlY2llcyAoMC41N8KxMC4yNykgYW5kIHRob3NlIHdpdGhvdXQgKDAuNzPCsTAuMjQpIChwIDwgMC4wMDAxKQoKCiMjIEJlYWsgR2FwZSBGRGl2CmBgYHtyfQpnZ3Bsb3QoY29tbXVuaXR5X2RhdGFfd2l0aF9pbnRyb2R1Y3Rpb25zLCBhZXMoeCA9IGhhc19pbnRyb2R1Y2VkX3NwZWNpZXMsIHkgPSBiZWFrX3dpZHRoX2ZkaXZfc3RhbmRhcmQpKSArIGdlb21fYm94cGxvdCgpCmBgYAoKYGBge3J9CndpbGNveC50ZXN0KGJlYWtfd2lkdGhfZmRpdl9zdGFuZGFyZCB+IGhhc19pbnRyb2R1Y2VkX3NwZWNpZXMsIGNvbW11bml0eV9kYXRhX3dpdGhfaW50cm9kdWN0aW9ucywgbmEuYWN0aW9uID0gJ25hLm9taXQnKQpgYGAKVGhlcmUgaXMgTk9UIGEgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSByZXNwb25zZSBvZiBjaXRpZXMgd2l0aCBpbnRyb2R1Y2VkIHNwZWNpZXMgKDAuNjHCsTAuMzApIGFuZCB0aG9zZSB3aXRob3V0ICgwLjU2wrEwLjI3KQoKCiMjIEhXSSBGRGl2CmBgYHtyfQpnZ3Bsb3QoY29tbXVuaXR5X2RhdGFfd2l0aF9pbnRyb2R1Y3Rpb25zLCBhZXMoeCA9IGhhc19pbnRyb2R1Y2VkX3NwZWNpZXMsIHkgPSBod2lfZmRpdl9zdGFuZGFyZCkpICsgZ2VvbV9ib3hwbG90KCkKYGBgCgpgYGB7cn0Kd2lsY294LnRlc3QoaHdpX2ZkaXZfc3RhbmRhcmQgfiBoYXNfaW50cm9kdWNlZF9zcGVjaWVzLCBjb21tdW5pdHlfZGF0YV93aXRoX2ludHJvZHVjdGlvbnMsIG5hLmFjdGlvbiA9ICduYS5vbWl0JykKYGBgClRoZXJlIGlzIGEgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSByZXNwb25zZSBvZiBjaXRpZXMgd2l0aCBpbnRyb2R1Y2VkIHNwZWNpZXMgKDAuNDnCsTAuMzApIGFuZCB0aG9zZSB3aXRob3V0ICgwLjc5wrEwLjIxKSAocCA8IDAuMDAwMSkKCgojIEV4YW1pbmUgaW5kaXZpZHVhbCBtZXRyaWNzCgojIyBBbmFseXNpcyBkYXRhIGZyYW1lCmBgYHtyfQpnZW9ncmFwaHkgPSByZWFkX2NzdihmaWxlbmFtZShDSVRZX0RBVEFfT1VUUFVUX0RJUiwgJ2dlb2dyYXBoeS5jc3YnKSkKbmFtZXMoZ2VvZ3JhcGh5KQpgYGAKCmBgYHtyfQphbmFseXNpc19kYXRhID0gY29tbXVuaXR5X2RhdGFfd2l0aF9yZWFsbVssYygnY2l0eV9pZCcsICdtbnRkX3N0YW5kYXJkJywgJ21hc3NfZmRpdl9zdGFuZGFyZCcsICdiZWFrX3dpZHRoX2ZkaXZfc3RhbmRhcmQnLCAnaHdpX2ZkaXZfc3RhbmRhcmQnLCAnY29yZV9yZWFsbScpXSAlPiUgCiAgbGVmdF9qb2luKGNpdHlfcG9pbnRzWyxjKCdjaXR5X2lkJywgJ2xhdGl0dWRlJywgJ2xvbmdpdHVkZScpXSkgJT4lCiAgbGVmdF9qb2luKGNvbW11bml0eV9kYXRhX3dpdGhfaW50cm9kdWN0aW9uc1ssYygnY2l0eV9pZCcsICdoYXNfaW50cm9kdWNlZF9zcGVjaWVzJyldKSAlPiUKICBsZWZ0X2pvaW4oZ2VvZ3JhcGh5KQoKYW5hbHlzaXNfZGF0YSRhYnNfbGF0aXR1ZGUgPSBhYnMoYW5hbHlzaXNfZGF0YSRsYXRpdHVkZSkKYW5hbHlzaXNfZGF0YSRjb3JlX3JlYWxtID0gZmFjdG9yKGFuYWx5c2lzX2RhdGEkY29yZV9yZWFsbSwgbGV2ZWxzID0gYygnUGFsZWFyY3RpYycsICdOZWFyY3RpYycsICdOZW90cm9waWMnLCAnQWZyb3Ryb3BpYycsICdJbmRvbWFsYXlhbicsICdBdXN0cmFsYXNpYScsICdPY2VhbmlhJykpCmFuYWx5c2lzX2RhdGEkaGFzX2ludHJvZHVjZWRfc3BlY2llcyA9IGZhY3RvcihhbmFseXNpc19kYXRhJGhhc19pbnRyb2R1Y2VkX3NwZWNpZXMsIGxldmVsID0gYygnVFJVRScsICdGQUxTRScpLCBsYWJlbHMgPSBjKCdJbnRyb2R1Y2VkIHNwZWNpZXMnLCAnTm8gaW50cm9kdWNlZCBzcGVjaWVzJykpCmBgYAoKYGBge3J9Cm1vZGVsX2RhdGEgPSBmdW5jdGlvbihkZiwgZGVwZW5kYW50X3ZhcikgewogIGRmWyxjKGRlcGVuZGFudF92YXIsICdjb3JlX3JlYWxtJywgJ2Fic19sYXRpdHVkZScsICdsb25naXR1ZGUnLCAnaGFzX2ludHJvZHVjZWRfc3BlY2llcycsICdjaXR5X2F2Z19uZHZpJywgJ2NpdHlfYXZnX2VsZXZhdGlvbicsICdjaXR5X2F2Z190ZW1wJywgJ2NpdHlfYXZnX21pbl9tb250aGx5X3RlbXAnLCAnY2l0eV9hdmdfbWF4X21vbnRobHlfdGVtcCcsICdjaXR5X2F2Z19tb250aGx5X3RlbXAnLCAnY2l0eV9hdmdfcmFpbmZhbGwnLCAnY2l0eV9hdmdfbWF4X21vbnRobHlfcmFpbmZhbGwnLCAnY2l0eV9hdmdfbWluX21vbnRobHlfcmFpbmZhbGwnLCAnY2l0eV9hdmdfc29pbF9tb2lzdHVyZScsICdjaXR5X21heF9lbGV2JywgJ2NpdHlfbWluX2VsZXYnLCAnY2l0eV9lbGV2X3JhbmdlJywgJ3JlZ2lvbl8yMGttX2F2Z19uZHZpJywgJ3JlZ2lvbl8yMGttX2F2Z19lbGV2YXRpb24nLCAncmVnaW9uXzIwa21fYXZnX3NvaWxfbW9pc3R1cmUnLCAncmVnaW9uXzIwa21fbWF4X2VsZXYnLCAncmVnaW9uXzIwa21fbWluX2VsZXYnLCAncmVnaW9uXzIwa21fZWxldl9yYW5nZScsICdyZWdpb25fNTBrbV9hdmdfbmR2aScsICdyZWdpb25fNTBrbV9hdmdfZWxldmF0aW9uJywgJ3JlZ2lvbl81MGttX2F2Z19zb2lsX21vaXN0dXJlJywgJ3JlZ2lvbl81MGttX21heF9lbGV2JywgJ3JlZ2lvbl81MGttX21pbl9lbGV2JywgJ3JlZ2lvbl81MGttX2VsZXZfcmFuZ2UnKV0KfQptb2RlbF9kYXRhKGFuYWx5c2lzX2RhdGEsICdtbnRkX3N0YW5kYXJkJykKYGBgCgpgYGB7cn0KbmFtZXMoYW5hbHlzaXNfZGF0YSkKYGBgCgpgYGB7cn0KYWxsX2V4cGxhbmF0b3JpZXMgPSBjKAogICAgJ2Fic19sYXRpdHVkZScsICdsYXRpdHVkZScsICdsb25naXR1ZGUnLCAKICAgICdoYXNfaW50cm9kdWNlZF9zcGVjaWVzJywKICAgICdjaXR5X2F2Z19uZHZpJywgJ2NpdHlfYXZnX2VsZXZhdGlvbicsICdjaXR5X2F2Z190ZW1wJywgJ2NpdHlfYXZnX21pbl9tb250aGx5X3RlbXAnLCAnY2l0eV9hdmdfbWF4X21vbnRobHlfdGVtcCcsIAogICAgJ2NpdHlfYXZnX21vbnRobHlfdGVtcCcsICdjaXR5X2F2Z19yYWluZmFsbCcsICdjaXR5X2F2Z19tYXhfbW9udGhseV9yYWluZmFsbCcsICdjaXR5X2F2Z19taW5fbW9udGhseV9yYWluZmFsbCcsIAogICAgJ2NpdHlfYXZnX3NvaWxfbW9pc3R1cmUnLCAnY2l0eV9tYXhfZWxldicsICdjaXR5X21pbl9lbGV2JywgJ2NpdHlfZWxldl9yYW5nZScsCiAgICAncmVnaW9uXzIwa21fYXZnX25kdmknLCAncmVnaW9uXzIwa21fYXZnX2VsZXZhdGlvbicsICdyZWdpb25fMjBrbV9hdmdfc29pbF9tb2lzdHVyZScsICdyZWdpb25fMjBrbV9tYXhfZWxldicsIAogICAgJ3JlZ2lvbl8yMGttX21pbl9lbGV2JywgJ3JlZ2lvbl8yMGttX2VsZXZfcmFuZ2UnLAogICAgJ3JlZ2lvbl81MGttX2F2Z19uZHZpJywgJ3JlZ2lvbl81MGttX2F2Z19lbGV2YXRpb24nLCAncmVnaW9uXzUwa21fYXZnX3NvaWxfbW9pc3R1cmUnLCAncmVnaW9uXzUwa21fbWF4X2VsZXYnLCAKICAgICdyZWdpb25fNTBrbV9taW5fZWxldicsICdyZWdpb25fNTBrbV9lbGV2X3JhbmdlJywKICAgICdjb3JlX3JlYWxtQWZyb3Ryb3BpYycsICdjb3JlX3JlYWxtQXVzdHJhbGFzaWEnLCAnY29yZV9yZWFsbUluZG9tYWxheWFuJywgJ2NvcmVfcmVhbG1OZWFyY3RpYycsICdjb3JlX3JlYWxtTmVvdHJvcGljJywgJ2NvcmVfcmVhbG1QYWxlYXJjdGljJykKCnR5cGVfbGFiZWxzID0gZnVuY3Rpb24ocCkgewogIGV4cGxhbmF0b3J5X2xldmVscyA9IGFsbF9leHBsYW5hdG9yaWVzW2FsbF9leHBsYW5hdG9yaWVzICVpbiUgcCRleHBsYW5hdG9yeV0KICBwJGV4cGxhbmF0b3J5IDwtIGZhY3RvcihwJGV4cGxhbmF0b3J5LCBsZXZlbHMgPSBleHBsYW5hdG9yeV9sZXZlbHMpCiAgCiAgcCR0eXBlIDwtICdSZWFsbScKICBwJHR5cGVbcCRleHBsYW5hdG9yeSAlaW4lIGMoJ2NpdHlfYXZnX25kdmknLCAnY2l0eV9hdmdfZWxldmF0aW9uJywgJ2NpdHlfYXZnX3RlbXAnLCAnY2l0eV9hdmdfbWluX21vbnRobHlfdGVtcCcsICdjaXR5X2F2Z19tYXhfbW9udGhseV90ZW1wJywgCiAgICAnY2l0eV9hdmdfbW9udGhseV90ZW1wJywgJ2NpdHlfYXZnX3JhaW5mYWxsJywgJ2NpdHlfYXZnX21heF9tb250aGx5X3JhaW5mYWxsJywgJ2NpdHlfYXZnX21pbl9tb250aGx5X3JhaW5mYWxsJywgCiAgICAnY2l0eV9hdmdfc29pbF9tb2lzdHVyZScsICdjaXR5X21heF9lbGV2JywgJ2NpdHlfbWluX2VsZXYnLCAnY2l0eV9lbGV2X3JhbmdlJyldIDwtICdDaXR5IGdlb2dyYXBoeScKICBwJHR5cGVbcCRleHBsYW5hdG9yeSAlaW4lIGMoJ3JlZ2lvbl81MGttX2F2Z19uZHZpJywgJ3JlZ2lvbl81MGttX2F2Z19lbGV2YXRpb24nLCAncmVnaW9uXzUwa21fYXZnX3NvaWxfbW9pc3R1cmUnLCAncmVnaW9uXzUwa21fbWF4X2VsZXYnLCAKICAgICdyZWdpb25fNTBrbV9taW5fZWxldicsICdyZWdpb25fNTBrbV9lbGV2X3JhbmdlJyldIDwtICdSZWdpb25hbCAoNTBrbSkgZ2VvZ3JhcGh5JwogICBwJHR5cGVbcCRleHBsYW5hdG9yeSAlaW4lIGMoJ3JlZ2lvbl8yMGttX2F2Z19uZHZpJywgJ3JlZ2lvbl8yMGttX2F2Z19lbGV2YXRpb24nLCAncmVnaW9uXzIwa21fYXZnX3NvaWxfbW9pc3R1cmUnLCAncmVnaW9uXzIwa21fbWF4X2VsZXYnLCAKICAgICdyZWdpb25fMjBrbV9taW5fZWxldicsICdyZWdpb25fMjBrbV9lbGV2X3JhbmdlJyldIDwtICdSZWdpb25hbCAoMjBrbSkgZ2VvZ3JhcGh5JwogIHAkdHlwZVtwJGV4cGxhbmF0b3J5ICVpbiUgYygnYWJzX2xhdGl0dWRlJywgJ2xvbmdpdHVkZScpXSA8LSAnU3BhdGlhbCcKICBwCn0KYGBgCgpgYGB7cn0KZXhwbGFuYXRvcnlfbGFiZWxzID0gYygKICAnaGFzX2ludHJvZHVjZWRfc3BlY2llcyc9J0hhcyBpbnRyb2R1Y2VkIHNwZWNpZXMnLCAKICAnY2l0eV9hdmdfbmR2aSc9J0F2ZXJhZ2UgTkRWSScsIAogICdjaXR5X2F2Z19lbGV2YXRpb24nPSdBdmVyYWdlIGVsZXZhdGlvbicsIAogICdjaXR5X2F2Z190ZW1wJz0nQXZlcmFnZSB0ZW1wZXJhdHVyZScsIAogICdjaXR5X2F2Z19taW5fbW9udGhseV90ZW1wJz0nQXZlcmFnZSBtaW5pbXVtIG1vbnRobHkgdGVtcGVyYXR1cmUnLCAKICAnY2l0eV9hdmdfbWF4X21vbnRobHlfdGVtcCc9J0F2ZXJhZ2UgbWF4aW11bSBtb250aGx5IHRlbXBlcmF0dXJlJywgCiAgJ2NpdHlfYXZnX21vbnRobHlfdGVtcCc9J0F2ZXJhZ2UgbW9udGhseSB0ZW1wZXJhdHVyZScsIAogICdjaXR5X2F2Z19yYWluZmFsbCc9J0F2ZXJhZ2UgcmFpbmZhbGwnLCAKICAnY2l0eV9hdmdfbWF4X21vbnRobHlfcmFpbmZhbGwnPSdBdmVyYWdlIG1heGltdW0gbW9udGhseSByYWluZmFsbCcsIAogICdjaXR5X2F2Z19taW5fbW9udGhseV9yYWluZmFsbCc9J0F2ZXJhZ2UgbWluaW11bSBtb250aGx5IHJhaW5mYWxsJywgCiAgJ2NpdHlfYXZnX3NvaWxfbW9pc3R1cmUnPSdBdmVyYWdlIHNvaWwgbW9pc3R1cmUnLCAKICAnY2l0eV9tYXhfZWxldic9J01heGltdW0gZWxldmF0aW9uJywgCiAgJ2NpdHlfbWluX2VsZXYnPSdNaW5pbXVtIGVsZXZhdGlvbicsIAogICdjaXR5X2VsZXZfcmFuZ2UnPSdFbGV2YXRpb24gcmFuZ2UnLCAKICAncmVnaW9uXzIwa21fYXZnX25kdmknPSdBdmVyYWdlIE5EVkknLCAKICAncmVnaW9uXzIwa21fYXZnX2VsZXZhdGlvbic9J0F2ZXJhZ2UgZWxldmF0aW9uJywgCiAgJ3JlZ2lvbl8yMGttX2F2Z19zb2lsX21vaXN0dXJlJz0nQXZlcmFnZSBzb2lsIG1vaXN0dXJlJywgCiAgJ3JlZ2lvbl8yMGttX21heF9lbGV2Jz0nTWF4aW11bSBlbGV2YXRpb24nLCAKICAncmVnaW9uXzIwa21fbWluX2VsZXYnPSdNaW5pbXVtIGVsZXZhdGlvbicsCiAgJ3JlZ2lvbl8yMGttX2VsZXZfcmFuZ2UnPSdFbGV2YXRpb24gcmFuZ2UnLAogICdyZWdpb25fNTBrbV9hdmdfbmR2aSc9J0F2ZXJhZ2UgTkRWSScsCiAgJ3JlZ2lvbl81MGttX2F2Z19lbGV2YXRpb24nPSdBdmVyYWdlIGVsZXZhdGlvbicsCiAgJ3JlZ2lvbl81MGttX2F2Z19zb2lsX21vaXN0dXJlJz0nQXZlcmFnZSBzb2lsIG1vaXN0dXJlJywgCiAgJ3JlZ2lvbl81MGttX21heF9lbGV2Jz0nTWF4aW11bSBlbGV2YXRpb24nLAogICdyZWdpb25fNTBrbV9taW5fZWxldic9J01pbmltdW0gZWxldmF0aW9uJywgCiAgJ3JlZ2lvbl81MGttX2VsZXZfcmFuZ2UnPSdFbGV2YXRpb24gcmFuZ2UnLAogICdhYnNfbGF0aXR1ZGUnID0gJ0Fic29sdXRlIGxhdGl0dWRlJywKICAnbGF0aXR1ZGUnID0gJ0xhdGl0dWRlJywKICAnbG9uZ2l0dWRlJyA9ICdMb25naXR1ZGUnLAogICdjb3JlX3JlYWxtQWZyb3Ryb3BpYycgPSAnQWZyb3Ryb3BpY2FsJywgCiAgJ2NvcmVfcmVhbG1BdXN0cmFsYXNpYScgPSAnQXVzdGFsaWFzaWFuJywgCiAgJ2NvcmVfcmVhbG1JbmRvbWFsYXlhbicgPSAnSW5kb21hbGF5YW4nLCAKICAnY29yZV9yZWFsbU5lYXJjdGljJyA9ICdOZWFyY3RpYycsIAogICdjb3JlX3JlYWxtTmVvdHJvcGljJyA9ICdOZW90cm9waWNhbCcsCiAgJ2NvcmVfcmVhbG1QYWxlYXJjdGljJyA9ICdQYWxlYXJjdGljJywKICAnY29yZV9yZWFsbU9jZWFuaWEnID0gJ09jZWFuaWNhbCcpCmBgYAoKIyMgSGVscGVyIHBsb3QgZnVuY3Rpb25zCmBgYHtyfQpnZW9tX21hcCA9IGZ1bmN0aW9uKG1hcF9zZiwgdGl0bGUpIHsKICBub3JtX21udGRfYW5hbHlzaXNfZ2VvID0gZ2dwbG90KCkgKyAKICAgIGdlb21fc2YoZGF0YSA9IHdvcmxkX21hcCwgYWVzKGdlb21ldHJ5ID0gZ2VvbWV0cnkpKSArCiAgICBtYXBfc2YgKwogICAgc3RhbmRhcmRpc2VkX2NvbG91cnNfc2NhbGUgKwogICAgbGFicyhjb2xvdXIgPSAnU3RhbmRhcmRpc2VkXG5SZXNwb25zZScpICsKICAgIHRoZW1lX2J3KCkgKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iKQp9CmBgYAoKIyMgSGVscGVyIERyZWRnZSBmdW5jdGlvbnMKYGBge3J9CiMgVGFrZW4gZnJvbSBNdU1JTiBwYWNrYWdlCiMgaHR0cHM6Ly9yZHJyLmlvL2NyYW4vTXVNSW4vc3JjL1IvYXZlcmFnaW5nLlIKIyBodHRwczovL3JkcnIuaW8vY3Jhbi9NdU1Jbi9zcmMvUi9tb2RlbC5hdmcuUgoKLmNvZWZhcnIuYXZnIDwtCiAgZnVuY3Rpb24oY2ZhcnIsIHdlaWdodCwgcmV2aXNlZC52YXIsIGZ1bGwsIGFscGhhKSB7CQogICAgd2VpZ2h0IDwtIHdlaWdodCAvIHN1bSh3ZWlnaHQpCiAgICBuQ29lZiA8LSBkaW0oY2ZhcnIpWzNMXQogICAgaWYoZnVsbCkgewogICAgICBuYXMgPC0gaXMubmEoY2ZhcnJbLCAxTCwgXSkgJiBpcy5uYShjZmFyclssIDJMLCBdKQogICAgICBjZmFyclssIDFMLCBdW25hc10gPC0gY2ZhcnJbLCAyTCwgXVtuYXNdIDwtIDAKICAgICAgI2NmYXJyWywgMUw6MkwsIF1baXMubmEoY2ZhcnJbLCAxTDoyTCwgXSldIDwtIDAKICAgICAgaWYoIWFsbChpcy5uYShjZmFyclssIDNMLCBdKSkpCiAgICAgICAgY2ZhcnJbICwzTCwgXVtpcy5uYShjZmFyclsgLCAzTCwgXSldIDwtIEluZgogICAgfQogICAgCiAgICBhdmdjb2VmIDwtIGFycmF5KGRpbSA9IGMobkNvZWYsIDVMKSwKICAgICAgICAgICAgICAgICAgICAgZGltbmFtZXMgPSBsaXN0KGRpbW5hbWVzKGNmYXJyKVtbM0xdXSwgYygiRXN0aW1hdGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdGQuIEVycm9yIiwgIkFkanVzdGVkIFNFIiwgIkxvd2VyIENJIiwgIlVwcGVyIENJIikpKQogICAgZm9yKGkgaW4gc2VxX2xlbihuQ29lZikpCiAgICAgIGF2Z2NvZWZbaSwgXSA8LSBwYXIuYXZnKGNmYXJyWywgMUwsIGldLCBjZmFyclssIDJMLCBpXSwgd2VpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZiA9IGNmYXJyWywgM0wsIGldLCBhbHBoYSA9IGFscGhhLCByZXZpc2VkLnZhciA9IHJldmlzZWQudmFyKQogICAgCiAgICBhdmdjb2VmW2lzLm5hbihhdmdjb2VmKV0gPC0gTkEKICAgIHJldHVybihhdmdjb2VmKQogIH0KCi5tYWtlY29lZm1hdCA8LSBmdW5jdGlvbihjZikgewogIG5vLmFzZSA8LSBhbGwoaXMubmEoY2ZbLCAzTF0pKQogIHogPC0gYWJzKGNmWywgMUxdIC8gY2ZbLCBpZihuby5hc2UpIDJMIGVsc2UgM0xdKQogIHB2YWwgPC0gMiAqIHBub3JtKHosIGxvd2VyLnRhaWwgPSBGQUxTRSkKICBjYmluZChjZlssIGlmKG5vLmFzZSkgMUw6MkwgZWxzZSAxTDozTCwgZHJvcCA9IEZBTFNFXSwKICAgICAgICBgeiB2YWx1ZWAgPSB6LCBgUHIoPnx6fClgID0gemFwc21hbGwocHZhbCkpCn0KCiMgR2VuZXJhdGUgbW9kZWwgc2VsZWN0aW9ucyB1c2luZyBsbWVyLCBkcmVkZ2UsIGFuZCBtb2RlbC5hdmcKIyBgZm9ydW1sYWAgOiBhIHR3by1zaWRlZCBsaW5lYXIgZm9ybXVsYSBvYmplY3QgZGVzY3JpYmluZyBib3RoIHRoZSBmaXhlZC1lZmZlY3RzIGFuZCByYW5kb20tZWZmZWN0cyBwYXJ0IG9mIHRoZSBtb2RlbAojIGBkYXRhYCA6IHRoZSBkYXRhIGZyYW1lIGNvbnRhaW5pbmcgdGhlIHZhcmlhYmxlcyBmcm9tIHRoZSBmb3JtdWxhCiMgYGFpY19kZWx0YWAgOiB0aGUgQUlDIGRlbHRhIHRvIHVzZSBmb3Igc2VsZWN0aW5nIG1vZGVscyBpbiBtb2RlbCBhdmVyYWdlCm1vZGVsX2F2ZXJhZ2UgPC0gZnVuY3Rpb24oZm9ybXVsYSwgZGF0YSwgYWljX2RlbHRhID0gMjApIHsKICBtb2RlbCA8LSBsbSgKICAgIGZvcm11bGEsCiAgICBkYXRhPWRhdGEKICApCiAgZHJlZGdlX3Jlc3VsdCA8LSBkcmVkZ2UobW9kZWwpCiAgc3VtbWFyeShtb2RlbC5hdmcoZHJlZGdlX3Jlc3VsdCwgc3Vic2V0ID0gZGVsdGEgPCBhaWNfZGVsdGEpKQp9CgojIENyZWF0ZSBhIHN1bW1hcnkgZGF0YSBmcmFtZSBjb250YWluaW5nIHRoZSBzZWxlY3RlZCB2YXJpYWJsZXMgZnJvbSBhIG1vZGVsCiMgYG1vZGVsX3N1bWAgOiBUaGUgbW9kZWwgc3VtbWFyeSBvdXRwdXQgZnJvbSBgbW9kZWxfYXZlcmFnZWAKbW9kZWxfc3VtbWFyeSA8LSBmdW5jdGlvbihtb2RlbF9zdW0pIHsKICAuY29sdW1uX25hbWUgPC0gZnVuY3Rpb24ocG9zdGZpeCkgewogICAgcG9zdGZpeAogIH0KICAKICAjIGp1c3QgcmV0dXJuIHRoZSBlc3RpbWF0ZSBhbmQgcCB2YWx1ZQogIHdlaWdodCA8LSBtb2RlbF9zdW0kbXNUYWJsZVssIDVMXQogIAogIGNvZWZtYXQuZnVsbCA8LSBhcy5kYXRhLmZyYW1lKC5tYWtlY29lZm1hdCguY29lZmFyci5hdmcobW9kZWxfc3VtJGNvZWZBcnJheSwgd2VpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cihtb2RlbF9zdW0sICJyZXZpc2VkLnZhciIpLCBUUlVFLCAwLjA1KSkpCiAgCiAgY29lZm1hdC5zdWJzZXQgPC0KICAgIGFzLmRhdGEuZnJhbWUoLm1ha2Vjb2VmbWF0KC5jb2VmYXJyLmF2Zyhtb2RlbF9zdW0kY29lZkFycmF5LCB3ZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cihtb2RlbF9zdW0sICJyZXZpc2VkLnZhciIpLCBGQUxTRSwgMC4wNSkpKQogIAogIAogIGNvZWZtYXQuc3Vic2V0IDwtIGNvZWZtYXQuc3Vic2V0Wy1jKDEpLCBjKDEsIDIsIDUpXQogIG5hbWVzKGNvZWZtYXQuc3Vic2V0KSA8LSBjKC5jb2x1bW5fbmFtZSgiZXN0aW1hdGUiKSwgLmNvbHVtbl9uYW1lKCJlcnJvciIpLCAuY29sdW1uX25hbWUoInAiKSkKICBjb2VmbWF0LnN1YnNldCA8LSB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbihjb2VmbWF0LnN1YnNldCwgImV4cGxhbmF0b3J5IikKICBjb2VmbWF0LnN1YnNldCRtb2RlbCA9ICdzdWJzZXQnCiAgCiAgY29lZm1hdC5mdWxsIDwtIGNvZWZtYXQuZnVsbFstYygxKSwgYygxLCAyLCA1KV0KICBuYW1lcyhjb2VmbWF0LmZ1bGwpIDwtIGMoLmNvbHVtbl9uYW1lKCJlc3RpbWF0ZSIpLCAuY29sdW1uX25hbWUoImVycm9yIiksIC5jb2x1bW5fbmFtZSgicCIpKQogIGNvZWZtYXQuZnVsbCA8LSB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbihjb2VmbWF0LmZ1bGwsICJleHBsYW5hdG9yeSIpCiAgY29lZm1hdC5mdWxsJG1vZGVsID0gJ2Z1bGwnCiAgCiAgcmJpbmQoY29lZm1hdC5mdWxsLCBjb2VmbWF0LnN1YnNldCkKfQpgYGAKCmBgYHtyfQpmb3JtdWxhX2Zyb21fdnN1cnAgPSBmdW5jdGlvbihwcmVkaWN0b3JzLCBkZXBlbmRlbnQsIHZzdXJwX3Jlc3VsdCkgewogIGFzLmZvcm11bGEocGFzdGUoZGVwZW5kZW50LCBwYXN0ZShuYW1lcyhwcmVkaWN0b3JzWyx2c3VycF9yZXN1bHQkdmFyc2VsZWN0LmludGVycF0pLCBjb2xsYXBzZT0iKyIpLCBzZXAgPSAifiIpKQp9CmBgYAoKYGBge3J9CnBsb3RfdnN1cnBfcmVzdWx0ID0gZnVuY3Rpb24ocmVzdWx0X3RhYmxlKSB7CiAgcCA9IHJlc3VsdF90YWJsZVtyZXN1bHRfdGFibGUkbW9kZWwgPT0gJ2Z1bGwnLF0KICBwID0gdHlwZV9sYWJlbHMocCkKCiAgZ2dwbG90KHAsIGFlcyh5PWV4cGxhbmF0b3J5LCB4PWVzdGltYXRlLCBjb2xvdXIgPSB0eXBlKSkgKyAKICAgIGdlb21fbGluZSgpICsKICAgIGdlb21fcG9pbnQoKSsKICAgIGdlb21fZXJyb3JiYXIoYWVzKHhtaW49ZXN0aW1hdGUtZXJyb3IsIHhtYXg9ZXN0aW1hdGUrZXJyb3IpLCB3aWR0aD0uMiwKICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKDAuMDUpKSArCiAgICBzY2FsZV95X2Rpc2NyZXRlKAogICAgICBsaW1pdHMgPSByZXYobGV2ZWxzKHAkZXhwbGFuYXRvcnkpKSwgCiAgICAgIGxhYmVscyA9IGV4cGxhbmF0b3J5X2xhYmVscykgKwogICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKGNvbG91cjEsIGNvbG91cjIsIGNvbG91cjMsIGNvbG91cjQsIGNvbG91cjUsIGNvbG91cjYpLCBicmVha3MgPSBjKCdSZWFsbScsICdDaXR5IGdlb2dyYXBoeScsICdSZWdpb25hbCAoNTBrbSkgZ2VvZ3JhcGh5JywgJ1JlZ2lvbmFsICgyMGttKSBnZW9ncmFwaHknLCAnU3BhdGlhbCcpKSArCiAgICB0aGVtZV9idygpICsKICAgIGdlb21fdmxpbmUoeGludGVyY2VwdD0wLCBsaW5ldHlwZT0iZG90dGVkIikgKwogICAgZ3VpZGVzKGNvbG91cj1ndWlkZV9sZWdlbmQodGl0bGU9IlByZWRpY3RvciB0eXBlIikpICsgeGxhYignRGlmZmVyZW5jZSBpbiByZXNwb25zZSBmcm9tIDBcbmhhYml0YXQgZmlsdGVyaW5nICg8IDApIGFuZCBjb21wZXRpdGl2ZSBpbnRlcmFjdGlvbnMgKD4gMClcbsKxIFN0YW5kYXJkIEVycm9yJykgKyB5bGFiKCdQcmVkaWN0b3InKSArCiAgICB0aGVtZShsZWdlbmQuanVzdGlmaWNhdGlvbiA9ICJ0b3AiKQp9CmBgYAoKIyMgTU5URApgYGB7cn0Kc3RkX21udGRfYW5hbHlzaXNfZ2VvX3Bsb3QgPSBnZW9tX21hcChnZW9tX3NmKGRhdGEgPSBhbmFseXNpc19kYXRhLCBhZXMoY29sb3IgPSBtbnRkX3N0YW5kYXJkLCBnZW9tZXRyeSA9IGdlb21ldHJ5KSksICdNTlREJykKc3RkX21udGRfYW5hbHlzaXNfZ2VvX3Bsb3QKYGBgCgpgYGB7cn0Kc3RkX21udGRfYW5hbHlzaXNfZGF0YSA9IG1vZGVsX2RhdGEoYW5hbHlzaXNfZGF0YVshaXMubmEoYW5hbHlzaXNfZGF0YSRtbnRkX3N0YW5kYXJkKSxdLCAnbW50ZF9zdGFuZGFyZCcpCnN0ZF9tbnRkX2FuYWx5c2lzX3ByZWRpY3RvcnMgPSBzdGRfbW50ZF9hbmFseXNpc19kYXRhWywtMV0Kc3RkX21udGRfYW5hbHlzaXNfaW50ZXJwID0gVlNVUkYoeCA9IHN0ZF9tbnRkX2FuYWx5c2lzX3ByZWRpY3RvcnMsIHkgPSBzdGRfbW50ZF9hbmFseXNpc19kYXRhJG1udGRfc3RhbmRhcmQpCm5hbWVzKHN0ZF9tbnRkX2FuYWx5c2lzX3ByZWRpY3RvcnNbLHN0ZF9tbnRkX2FuYWx5c2lzX2ludGVycCR2YXJzZWxlY3QuaW50ZXJwXSkKYGBgCgpgYGB7cn0Kc3RkX21udGRfYW5hbHlzaXNfZm9ybXVsYSA9IGZvcm11bGFfZnJvbV92c3VycChzdGRfbW50ZF9hbmFseXNpc19wcmVkaWN0b3JzLCAibW50ZF9zdGFuZGFyZCIsIHN0ZF9tbnRkX2FuYWx5c2lzX2ludGVycCkKc3RkX21udGRfYW5hbHlzaXNfcmVzdWx0IDwtIG1vZGVsX2F2ZXJhZ2Uoc3RkX21udGRfYW5hbHlzaXNfZm9ybXVsYSwgc3RkX21udGRfYW5hbHlzaXNfZGF0YSkKc3RkX21udGRfYW5hbHlzaXNfcmVzdWx0X3RhYmxlID0gbW9kZWxfc3VtbWFyeShzdGRfbW50ZF9hbmFseXNpc19yZXN1bHQpCnN0ZF9tbnRkX2FuYWx5c2lzX3Jlc3VsdF90YWJsZQpgYGAKCmBgYHtyfQpzdGRfbW50ZF9hbmFseXNpc19wcmVkX3Bsb3QgPSBwbG90X3ZzdXJwX3Jlc3VsdChzdGRfbW50ZF9hbmFseXNpc19yZXN1bHRfdGFibGUpCnN0ZF9tbnRkX2FuYWx5c2lzX3ByZWRfcGxvdApgYGAKCiMjIEdhcGUgd2lkdGggLSBGRGl2CmBgYHtyfQpzdGRfZ2FwZV9mZGl2X2FuYWx5c2lzX2dlb19wbG90ID0gZ2VvbV9tYXAoZ2VvbV9zZihkYXRhID0gYW5hbHlzaXNfZGF0YSwgYWVzKGNvbG9yID0gYmVha193aWR0aF9mZGl2X3N0YW5kYXJkLCBnZW9tZXRyeSA9IGdlb21ldHJ5KSksICdCZWFrIFdpZHRoIEZEaXYnKQpzdGRfZ2FwZV9mZGl2X2FuYWx5c2lzX2dlb19wbG90CmBgYAoKYGBge3J9CnN0ZF9nYXBlX2ZkaXZfYW5hbHlzaXNfZGF0YSA9IG1vZGVsX2RhdGEoYW5hbHlzaXNfZGF0YVshaXMubmEoYW5hbHlzaXNfZGF0YSRiZWFrX3dpZHRoX2ZkaXZfc3RhbmRhcmQpLF0sICdiZWFrX3dpZHRoX2ZkaXZfc3RhbmRhcmQnKQpzdGRfZ2FwZV9mZGl2X2FuYWx5c2lzX3ByZWRpY3RvcnMgPSBzdGRfZ2FwZV9mZGl2X2FuYWx5c2lzX2RhdGFbLC0xXQpzdGRfZ2FwZV9mZGl2X2FuYWx5c2lzX2ludGVycCA9IFZTVVJGKHggPSBzdGRfZ2FwZV9mZGl2X2FuYWx5c2lzX3ByZWRpY3RvcnMsIHkgPSBzdGRfZ2FwZV9mZGl2X2FuYWx5c2lzX2RhdGEkYmVha193aWR0aF9mZGl2X3N0YW5kYXJkKQpuYW1lcyhzdGRfZ2FwZV9mZGl2X2FuYWx5c2lzX3ByZWRpY3RvcnNbLHN0ZF9nYXBlX2ZkaXZfYW5hbHlzaXNfaW50ZXJwJHZhcnNlbGVjdC5pbnRlcnBdKQpgYGAKCmBgYHtyfQpzdGRfZ2FwZV9mZGl2X2FuYWx5c2lzX2Zvcm11bGEgPSBmb3JtdWxhX2Zyb21fdnN1cnAoc3RkX2dhcGVfZmRpdl9hbmFseXNpc19wcmVkaWN0b3JzLCAiYmVha193aWR0aF9mZGl2X3N0YW5kYXJkIiwgc3RkX2dhcGVfZmRpdl9hbmFseXNpc19pbnRlcnApCnN0ZF9nYXBlX2ZkaXZfYW5hbHlzaXNfcmVzdWx0IDwtIG1vZGVsX2F2ZXJhZ2Uoc3RkX2dhcGVfZmRpdl9hbmFseXNpc19mb3JtdWxhLCBzdGRfZ2FwZV9mZGl2X2FuYWx5c2lzX2RhdGEpCnN0ZF9nYXBlX2ZkaXZfYW5hbHlzaXNfcmVzdWx0X3RhYmxlID0gbW9kZWxfc3VtbWFyeShzdGRfZ2FwZV9mZGl2X2FuYWx5c2lzX3Jlc3VsdCkKc3RkX2dhcGVfZmRpdl9hbmFseXNpc19yZXN1bHRfdGFibGUKYGBgCgpgYGB7cn0Kc3RkX2dhcGVfZmRpdl9hbmFseXNpc19wcmVkX3Bsb3QgPSBwbG90X3ZzdXJwX3Jlc3VsdChzdGRfZ2FwZV9mZGl2X2FuYWx5c2lzX3Jlc3VsdF90YWJsZSkKc3RkX2dhcGVfZmRpdl9hbmFseXNpc19wcmVkX3Bsb3QKYGBgCgoKIyMgSFdJIC0gRkRpdgpgYGB7cn0Kc3RkX2h3aV9mZGl2X2FuYWx5c2lzX2dlb19wbG90ID0gZ2VvbV9tYXAoZ2VvbV9zZihkYXRhID0gYW5hbHlzaXNfZGF0YSwgYWVzKGNvbG9yID0gaHdpX2ZkaXZfc3RhbmRhcmQsIGdlb21ldHJ5ID0gZ2VvbWV0cnkpKSwgJ0hXSSBGRGl2JykKc3RkX2h3aV9mZGl2X2FuYWx5c2lzX2dlb19wbG90CmBgYAoKYGBge3J9CnN0ZF9od2lfZmRpdl9hbmFseXNpc19kYXRhID0gbW9kZWxfZGF0YShhbmFseXNpc19kYXRhWyFpcy5uYShhbmFseXNpc19kYXRhJGh3aV9mZGl2X3N0YW5kYXJkKSxdLCAnaHdpX2ZkaXZfc3RhbmRhcmQnKQpzdGRfaHdpX2ZkaXZfYW5hbHlzaXNfcHJlZGljdG9ycyA9IHN0ZF9od2lfZmRpdl9hbmFseXNpc19kYXRhWywtMV0Kc3RkX2h3aV9mZGl2X2FuYWx5c2lzX2ludGVycCA9IFZTVVJGKHggPSBzdGRfaHdpX2ZkaXZfYW5hbHlzaXNfcHJlZGljdG9ycywgeSA9IHN0ZF9od2lfZmRpdl9hbmFseXNpc19kYXRhJGh3aV9mZGl2X3N0YW5kYXJkKQpuYW1lcyhzdGRfaHdpX2ZkaXZfYW5hbHlzaXNfcHJlZGljdG9yc1ssc3RkX2h3aV9mZGl2X2FuYWx5c2lzX2ludGVycCR2YXJzZWxlY3QuaW50ZXJwXSkKYGBgCgoKYGBge3J9CnN0ZF9od2lfZmRpdl9hbmFseXNpc19mb3JtdWxhID0gZm9ybXVsYV9mcm9tX3ZzdXJwKHN0ZF9od2lfZmRpdl9hbmFseXNpc19wcmVkaWN0b3JzLCAiaHdpX2ZkaXZfc3RhbmRhcmQiLCBzdGRfaHdpX2ZkaXZfYW5hbHlzaXNfaW50ZXJwKQpzdGRfaHdpX2ZkaXZfYW5hbHlzaXNfcmVzdWx0IDwtIG1vZGVsX2F2ZXJhZ2Uoc3RkX2h3aV9mZGl2X2FuYWx5c2lzX2Zvcm11bGEsIHN0ZF9od2lfZmRpdl9hbmFseXNpc19kYXRhKQpzdGRfaHdpX2ZkaXZfYW5hbHlzaXNfcmVzdWx0X3RhYmxlID0gbW9kZWxfc3VtbWFyeShzdGRfaHdpX2ZkaXZfYW5hbHlzaXNfcmVzdWx0KQpzdGRfaHdpX2ZkaXZfYW5hbHlzaXNfcmVzdWx0X3RhYmxlCmBgYAoKYGBge3J9CnN0ZF9od2lfZmRpdl9hbmFseXNpc19wcmVkX3Bsb3QgPSBwbG90X3ZzdXJwX3Jlc3VsdChzdGRfaHdpX2ZkaXZfYW5hbHlzaXNfcmVzdWx0X3RhYmxlKQpzdGRfaHdpX2ZkaXZfYW5hbHlzaXNfcHJlZF9wbG90CmBgYAoKCiMjIE1hc3MgLSBGRGl2CmBgYHtyfQpzdGRfbWFzc19mZGl2X2FuYWx5c2lzX2dlb19wbG90ID0gZ2VvbV9tYXAoZ2VvbV9zZihkYXRhID0gYW5hbHlzaXNfZGF0YSwgYWVzKGNvbG9yID0gbWFzc19mZGl2X3N0YW5kYXJkLCBnZW9tZXRyeSA9IGdlb21ldHJ5KSksICdNYXNzIEZEaXYnKQpzdGRfbWFzc19mZGl2X2FuYWx5c2lzX2dlb19wbG90CmBgYAoKYGBge3J9CnN0ZF9tYXNzX2ZkaXZfYW5hbHlzaXNfZGF0YSA9IG1vZGVsX2RhdGEoYW5hbHlzaXNfZGF0YVshaXMubmEoYW5hbHlzaXNfZGF0YSRtYXNzX2ZkaXZfc3RhbmRhcmQpLF0sICdtYXNzX2ZkaXZfc3RhbmRhcmQnKQpzdGRfbWFzc19mZGl2X2FuYWx5c2lzX3ByZWRpY3RvcnMgPSBzdGRfbWFzc19mZGl2X2FuYWx5c2lzX2RhdGFbLC0xXQpzdGRfbWFzc19mZGl2X2FuYWx5c2lzX2ludGVycCA9IFZTVVJGKHggPSBzdGRfbWFzc19mZGl2X2FuYWx5c2lzX3ByZWRpY3RvcnMsIHkgPSBzdGRfbWFzc19mZGl2X2FuYWx5c2lzX2RhdGEkbWFzc19mZGl2X3N0YW5kYXJkKQpuYW1lcyhzdGRfbWFzc19mZGl2X2FuYWx5c2lzX3ByZWRpY3RvcnNbLHN0ZF9tYXNzX2ZkaXZfYW5hbHlzaXNfaW50ZXJwJHZhcnNlbGVjdC5pbnRlcnBdKQpgYGAKCmBgYHtyfQpzdGRfbWFzc19mZGl2X2FuYWx5c2lzX2Zvcm11bGEgPSBmb3JtdWxhX2Zyb21fdnN1cnAoc3RkX21hc3NfZmRpdl9hbmFseXNpc19wcmVkaWN0b3JzLCAibWFzc19mZGl2X3N0YW5kYXJkIiwgc3RkX21hc3NfZmRpdl9hbmFseXNpc19pbnRlcnApCnN0ZF9tYXNzX2ZkaXZfYW5hbHlzaXNfcmVzdWx0IDwtIG1vZGVsX2F2ZXJhZ2Uoc3RkX21hc3NfZmRpdl9hbmFseXNpc19mb3JtdWxhLCBzdGRfbWFzc19mZGl2X2FuYWx5c2lzX2RhdGEpCnN0ZF9tYXNzX2ZkaXZfYW5hbHlzaXNfcmVzdWx0X3RhYmxlID0gbW9kZWxfc3VtbWFyeShzdGRfbWFzc19mZGl2X2FuYWx5c2lzX3Jlc3VsdCkKc3RkX21hc3NfZmRpdl9hbmFseXNpc19yZXN1bHRfdGFibGUKYGBgCgpgYGB7cn0Kc3RkX21hc3NfZmRpdl9hbmFseXNpc19wcmVkX3Bsb3QgPSBwbG90X3ZzdXJwX3Jlc3VsdChzdGRfbWFzc19mZGl2X2FuYWx5c2lzX3Jlc3VsdF90YWJsZSkKc3RkX21hc3NfZmRpdl9hbmFseXNpc19wcmVkX3Bsb3QKYGBgCgojIENyZWF0ZSBwbG90IG9mIGRpZmZlcmVuY2VzIGluIHByb2Nlc3MgcmVzcG9uc2UKYGBge3J9CnByZWRfbGVnZW5kIDwtIGdncHVicjo6Z2V0X2xlZ2VuZCgKICAjIGNyZWF0ZSBzb21lIHNwYWNlIHRvIHRoZSBsZWZ0IG9mIHRoZSBsZWdlbmQKICBzdGRfaHdpX2ZkaXZfYW5hbHlzaXNfcHJlZF9wbG90ICsgdGhlbWUobGVnZW5kLmJveC5tYXJnaW4gPSBtYXJnaW4oMCwgMCwgMCwgMCkpICsgZ3VpZGVzKGNvbG91cj1ndWlkZV9sZWdlbmQobmNvbD0yKSkgKyBsYWJzKGNvbG9yID0gIlByZWRpY3RvciB0eXBlIikKKQpnZW9fbGVnZW5kIDwtIGdncHVicjo6Z2V0X2xlZ2VuZCgKICAjIGNyZWF0ZSBzb21lIHNwYWNlIHRvIHRoZSBsZWZ0IG9mIHRoZSBsZWdlbmQKICBzdGRfbWFzc19mZGl2X2FuYWx5c2lzX2dlb19wbG90ICsgdGhlbWUobGVnZW5kLmJveC5tYXJnaW4gPSBtYXJnaW4oLTgwLCAwLCAwLCAxMiksIGxlZ2VuZC50aXRsZS5wb3NpdGlvbiA9ICJ0b3AiLCBsZWdlbmQua2V5LndpZHRoID0gdW5pdCgxMCwgJ21tJykpICsgbGFicyhjb2xvciA9ICJTdGFuZGFyZGlzZWQgcmVzcG9uc2UiKQopCgpsZWdlbmQgPSBwbG90X2dyaWQoCiAgZ2VvX2xlZ2VuZCwKICBwcmVkX2xlZ2VuZCwgCiAgbnJvdyA9IDEKKQpsZWdlbmQKYGBgCgpgYGB7cn0KcGxvdF9ncmlkKAogIHBsb3RfZ3JpZCgKICAgIHN0ZF9tbnRkX2FuYWx5c2lzX2dlb19wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIiksIAogICAgc3RkX21udGRfYW5hbHlzaXNfcHJlZF9wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKyBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICcnLCBsaW1pdHMgPSBjKC0zLCAzKSkgKyB5bGFiKCcnKSwgCiAgICBucm93ID0gMQogICkgKyBkcmF3X2xhYmVsKCJNTlREIiwgc2l6ZSA9IDE2LCBhbmdsZSA9IDkwLCB4ID0gMC4wMSwgeSA9IDAuNSksCiAgcGxvdF9ncmlkKAogICAgc3RkX2dhcGVfZmRpdl9hbmFseXNpc19nZW9fcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpLCAKICAgIHN0ZF9nYXBlX2ZkaXZfYW5hbHlzaXNfcHJlZF9wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKyBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICcnLCBsaW1pdHMgPSBjKC0zLCAzKSkgKyB5bGFiKCcnKSwgCiAgICBucm93ID0gMQogICkgKyBkcmF3X2xhYmVsKCJCZWFrIFdpZHRoIiwgc2l6ZSA9IDE2LCBhbmdsZSA9IDkwLCB4ID0gMC4wMSwgeSA9IDAuNSksCiAgcGxvdF9ncmlkKAogICAgc3RkX2h3aV9mZGl2X2FuYWx5c2lzX2dlb19wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIiksIAogICAgc3RkX2h3aV9mZGl2X2FuYWx5c2lzX3ByZWRfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICsgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAnJywgbGltaXRzID0gYygtMywgMykpICsgeWxhYignJyksIAogICAgbnJvdyA9IDEKICApICsgZHJhd19sYWJlbCgiSFdJIiwgc2l6ZSA9IDE2LCBhbmdsZSA9IDkwLCB4ID0gMC4wMSwgeSA9IDAuNSksCiAgcGxvdF9ncmlkKAogICAgc3RkX21hc3NfZmRpdl9hbmFseXNpc19nZW9fcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpLCAKICAgIHN0ZF9tYXNzX2ZkaXZfYW5hbHlzaXNfcHJlZF9wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKyBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICcnLCBsaW1pdHMgPSBjKC0zLCAzKSkgKyB5bGFiKCcnKSwgCiAgICBucm93ID0gMQogICkgKyBkcmF3X2xhYmVsKCJNYXNzIiwgc2l6ZSA9IDE2LCBhbmdsZSA9IDkwLCB4ID0gMC4wMSwgeSA9IDAuNSksIAogIGxlZ2VuZCwKICBucm93ID0gNQopCmdnc2F2ZShmaWxlbmFtZShGSUdVUkVTX09VVFBVVF9ESVIsICdwcm9jZXNzX3Jlc3BvbnNlLmpwZycpLCB3aWR0aCA9IDMwMDAsIGhlaWdodCA9IDMyMDAsIHVuaXRzID0gJ3B4JykKYGBgCgoKIyBDb21wYXJlIG1ldHJpY3MgYWdhaW5zdCBlYWNoIG90aGVyCmBgYHtyfQpnZ3Bsb3QoYW5hbHlzaXNfZGF0YSwgYWVzKHggPSBiZWFrX3dpZHRoX2ZkaXZfc3RhbmRhcmQsIHkgPSBtbnRkX3N0YW5kYXJkLCBjb2xvdXIgPSBjb3JlX3JlYWxtKSkgKyAKICBnZW9tX3BvaW50KCkgKwogIHlsYWIoIk1OVEQiKSArIAogIHhsYWIoIkJlYWsgV2lkdGggRkRpdiIpICsKICB0aGVtZV9idygpICsgbGFicyhjb2xvciA9ICJSZWFsbSIpCmBgYAoKYGBge3J9CmdncGxvdChhbmFseXNpc19kYXRhLCBhZXMoeCA9IGh3aV9mZGl2X3N0YW5kYXJkLCB5ID0gbW50ZF9zdGFuZGFyZCwgY29sb3VyID0gY29yZV9yZWFsbSkpICsgCiAgZ2VvbV9wb2ludCgpICsKICB5bGFiKCJNTlREIikgKyAKICB4bGFiKCJIV0kgRkRpdiIpICsKICB0aGVtZV9idygpICsgbGFicyhjb2xvciA9ICJSZWFsbSIpCmBgYAoKYGBge3J9CmdncGxvdChhbmFseXNpc19kYXRhLCBhZXMoeCA9IGh3aV9mZGl2X3N0YW5kYXJkLCB5ID0gYmVha193aWR0aF9mZGl2X3N0YW5kYXJkLCBjb2xvdXIgPSBjb3JlX3JlYWxtKSkgKyAKICBnZW9tX3BvaW50KCkgKwogIHlsYWIoIkJlYWsgV2lkdGggRkRpdiIpICsgCiAgeGxhYigiSFdJIEZEaXYiKSArCiAgdGhlbWVfYncoKSArIGxhYnMoY29sb3IgPSAiUmVhbG0iKQpgYGAKCmBgYHtyfQptbnRkX2ZkaXZfYW5hbHlzaXMgPSBhbmFseXNpc19kYXRhICU+JSAKICBkcGx5cjo6c2VsZWN0KGNpdHlfaWQsICBtbnRkX3N0YW5kYXJkLCBod2lfZmRpdl9zdGFuZGFyZCwgYmVha193aWR0aF9mZGl2X3N0YW5kYXJkLCBtYXNzX2ZkaXZfc3RhbmRhcmQpICU+JQogIGxlZnRfam9pbihjb21tdW5pdHlfc3VtbWFyeSkgJT4lCiAgbXV0YXRlKHVyYmFuX3Bvb2xfcGVyYyA9IHVyYmFuX3Bvb2xfc2l6ZSAqIDEwMCAvIHJlZ2lvbmFsX3Bvb2xfc2l6ZSkKbW50ZF9mZGl2X2FuYWx5c2lzCmBgYAoKYGBge3J9CmdncGFpcnMobW50ZF9mZGl2X2FuYWx5c2lzICU+JSBkcGx5cjo6c2VsZWN0KG1udGRfc3RhbmRhcmQsIGh3aV9mZGl2X3N0YW5kYXJkLCBiZWFrX3dpZHRoX2ZkaXZfc3RhbmRhcmQsIG1hc3NfZmRpdl9zdGFuZGFyZCwgcmVnaW9uYWxfcG9vbF9zaXplLCB1cmJhbl9wb29sX3NpemUsIHVyYmFuX3Bvb2xfcGVyYyksIGNvbHVtbkxhYmVscyA9IGMoJ01OVEQnLCAnSFdJIEZEJywgJ0JrIEZEJywgJ01zcyBGRCcsICdSZWdpb24gUmljaC4nLCAnVXJiYW4gUmljaC4nLCAnJSBVcmJhbicpKQpnZ3NhdmUoZmlsZW5hbWUoRklHVVJFU19PVVRQVVRfRElSLCAnYXBwZW5kaXhfc3RhbmRhcmlzZWRfY29ycmVsYXRpb24uanBnJykpCmBgYAoKCg==